Add 7 and update 2 files
Some checks failed
Test and Publish Templates / test-and-publish (push) Failing after 14s

This commit is contained in:
Your Name
2025-08-24 20:50:58 +12:00
parent f917e8cb4f
commit bedc68373d
9 changed files with 907 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
name: Test and Publish Templates
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test-and-publish:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch all history for change detection
- name: Install dependencies
run: |
# Install sos tool for uploading
curl -o /tmp/sos https://getbin.xyz/sos:latest && chmod +x /tmp/sos
sudo mv /tmp/sos /usr/local/bin/sos
# Install jq for JSON parsing
which jq || sudo apt-get update && sudo apt-get install -y jq
# Install tar for packaging
which tar || sudo apt-get update && sudo apt-get install -y tar
- name: Run tests
run: |
chmod +x test.sh
./test.sh
- name: Detect changed templates
id: changes
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: |
chmod +x detect-changes.sh
CHANGED_TEMPLATES=$(./detect-changes.sh)
if [ -z "$CHANGED_TEMPLATES" ]; then
echo "No templates have changed"
echo "changed=false" >> $GITHUB_OUTPUT
else
echo "Changed templates: $CHANGED_TEMPLATES"
echo "changed=true" >> $GITHUB_OUTPUT
# Store changed templates for the next step
echo "$CHANGED_TEMPLATES" > changed_templates.txt
fi
- name: Publish changed templates
if: github.ref == 'refs/heads/main' && github.event_name == 'push' && steps.changes.outputs.changed == 'true'
env:
SOS_WRITE_TOKEN: ${{ secrets.SOS_WRITE_TOKEN }}
run: |
chmod +x publish.sh
# Publish only changed templates
./publish.sh --changed-only
- name: Update versions after successful publish
if: github.ref == 'refs/heads/main' && github.event_name == 'push' && steps.changes.outputs.changed == 'true'
run: |
# This step would normally commit the updated versions.json
# But we'll leave this for manual version bumping
echo "Templates published successfully. Consider bumping versions in versions.json for the changed templates."

309
DEVELOPMENT.md Normal file
View File

@@ -0,0 +1,309 @@
# Development Guide
This guide covers the development workflow for dropshell templates, including testing, versioning, and publishing.
## Repository Structure
```
dropshell-templates/
├── .gitea/workflows/ # CI/CD workflows
├── caddy/ # Web server template
├── gitea-runner-docker/ # CI runner template
├── simple-object-server/ # Object storage template
├── squashkiwi/ # Squashkiwi service template
├── static-website/ # Static site hosting template
├── watchtower/ # Container auto-updater template
├── versions.json # Template version tracking
├── test.sh # Template validation script
├── publish.sh # Template publishing script
├── bump-version.sh # Version management script
├── detect-changes.sh # Change detection script
└── test_template.sh # Integration test script
```
## Template Structure
Each template must have:
- `install.sh` - Installation script
- `uninstall.sh` - Uninstallation script
- `start.sh` - Service start script
- `stop.sh` - Service stop script
- `status.sh` - Service status script
- `config/service.env` - Service configuration
Optional scripts:
- `logs.sh` - View service logs
- `backup.sh` - Backup service data
- `restore.sh` - Restore service data
- `ports.sh` - Display service ports
- `ssh.sh` - SSH into service container
- `destroy.sh` - Completely remove service
## Testing
### Local Testing
Run validation tests for all templates:
```bash
./test.sh
```
This checks:
- Required scripts exist
- Scripts are executable
- Config directory exists
- service.env file exists
- Shell script syntax is valid
### Integration Testing
If you have `ds` (dropshell) installed locally:
```bash
./test_template.sh caddy
```
This performs a full integration test:
- Creates a test service
- Installs the template
- Starts/stops the service
- Backs up and restores
- Destroys the service
## Version Management
Each template has independent semantic versioning tracked in `versions.json`.
### Version Format
Versions follow semantic versioning: `MAJOR.MINOR.PATCH`
- **MAJOR**: Breaking changes
- **MINOR**: New features, backwards compatible
- **PATCH**: Bug fixes, backwards compatible
### Bumping Versions
#### Single Template
```bash
# Bump patch version (1.0.0 -> 1.0.1)
./bump-version.sh caddy patch
# Bump minor version (1.0.0 -> 1.1.0)
./bump-version.sh caddy minor
# Bump major version (1.0.0 -> 2.0.0)
./bump-version.sh caddy major
# Set specific version
./bump-version.sh caddy 2.5.3
```
#### All Templates
```bash
# Bump patch for all templates
./bump-version.sh --all patch
# Set all templates to specific version
./bump-version.sh --all 2.0.0
```
### Version Workflow
1. **Make changes** to template(s)
2. **Test changes** locally:
```bash
./test.sh
# Optional: ./test_template.sh <template-name>
```
3. **Bump version** for changed templates:
```bash
# For bug fixes
./bump-version.sh caddy patch
# For new features
./bump-version.sh caddy minor
# For breaking changes
./bump-version.sh caddy major
```
4. **Commit changes** including `versions.json`:
```bash
git add .
git commit -m "feat(caddy): add custom domain support"
```
5. **Push to main** - CI automatically publishes changed templates
## Publishing
### Automatic Publishing (CI/CD)
When you push to the main branch:
1. CI runs tests on all templates
2. Detects which templates changed since last version update
3. Publishes only changed templates to templates.dropshell.app
4. Each template is tagged with:
- `:latest` - Always points to newest version
- `:1.0.0` - Specific version
- `:v1` - Major version only
### Manual Publishing
```bash
# Set environment variable
export SOS_WRITE_TOKEN=your-token-here
# Publish only changed templates (default)
./publish.sh
# Publish all templates
./publish.sh --all
# Publish specific templates
./publish.sh caddy watchtower
# Explicitly publish only changed
./publish.sh --changed-only
```
## Change Detection
The system automatically detects which templates have changed:
```bash
# List changed templates since last version update
./detect-changes.sh
# Output as JSON
./detect-changes.sh --json
```
Changes are detected by comparing against the last git tag that modified `versions.json`.
## CI/CD Configuration
The GitHub Actions workflow (`.gitea/workflows/test-and-publish.yaml`):
- Triggers on pushes to main and pull requests
- Runs tests for all templates
- Publishes only changed templates (main branch only)
- Requires `SOS_WRITE_TOKEN` secret in repository settings
### Setting up CI/CD
1. Go to your Gitea repository settings
2. Add a new secret named `SOS_WRITE_TOKEN`
3. Set the value to your Simple Object Server write token
4. Push to main branch to trigger the workflow
## Development Workflow Example
Here's a complete example of updating the caddy template:
```bash
# 1. Make changes to caddy template
vim caddy/config/Caddyfile
# 2. Test your changes
./test.sh
# 3. Run integration test (if ds is installed)
./test_template.sh caddy
# 4. Bump version (patch for bug fix)
./bump-version.sh caddy patch
# 5. Review version change
cat versions.json
# 6. Commit your changes
git add .
git commit -m "fix(caddy): correct reverse proxy configuration"
# 7. Push to trigger automatic publishing
git push origin main
```
The CI will:
- Run tests
- Detect that only caddy changed
- Publish caddy with new version (e.g., caddy:1.0.1, caddy:latest, caddy:v1)
## Best Practices
1. **Always test locally** before pushing
2. **Use semantic versioning** appropriately:
- Breaking changes = major bump
- New features = minor bump
- Bug fixes = patch bump
3. **Write clear commit messages** that explain the changes
4. **Update version before pushing** to main
5. **Document breaking changes** in commit messages
6. **Keep templates simple** and focused on single services
7. **Use environment variables** in service.env for configuration
8. **Test both install and uninstall** procedures
## Troubleshooting
### Tests failing locally
- Ensure all scripts are executable: `chmod +x template-name/*.sh`
- Check script syntax: `bash -n template-name/script.sh`
- Verify config directory exists
- Ensure service.env is present
### Publishing fails
- Verify `SOS_WRITE_TOKEN` is set
- Check that `sos` tool is installed
- Ensure versions.json is valid JSON
- Verify network connectivity to templates.dropshell.app
### Change detection not working
- Ensure git history is available: `git fetch --all`
- Check that versions.json was committed
- Verify detect-changes.sh is executable
## Template Guidelines
### Required Files
Every template must include:
- Core scripts: install.sh, uninstall.sh, start.sh, stop.sh, status.sh
- Configuration: config/service.env
### Script Requirements
- Use `#!/bin/bash` shebang
- Set `set -e` for error handling
- Use absolute paths where possible
- Handle missing dependencies gracefully
- Provide meaningful error messages
- Clean up resources on uninstall
### Environment Variables
Define in config/service.env:
- Service-specific configuration
- Port mappings
- Volume mounts
- Resource limits
- Feature flags
### Docker Integration
Most templates use Docker:
- Use official images when possible
- Pin specific versions (avoid :latest in production)
- Map configuration via volumes
- Use docker-compose for complex setups
- Handle container lifecycle properly
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add/update tests if needed
5. Bump versions appropriately
6. Submit a pull request
Pull requests should:
- Pass all tests
- Include version bumps for changed templates
- Have clear descriptions
- Follow existing code style
- Include any necessary documentation updates

162
bump-version.sh Executable file
View File

@@ -0,0 +1,162 @@
#!/bin/bash
set -e
SCRIPT_DIR=$(dirname "$0")
cd "$SCRIPT_DIR"
function die() {
echo "ERROR: $1" >&2
exit 1
}
function info() {
echo "INFO: $1"
}
function usage() {
cat << EOF
Usage: $0 <template> <version-type|version>
Arguments:
template Name of the template to version
version-type One of: major, minor, patch
version Specific version number (e.g., 2.1.0)
Examples:
$0 caddy patch # Bump patch version (1.0.0 -> 1.0.1)
$0 caddy minor # Bump minor version (1.0.0 -> 1.1.0)
$0 caddy major # Bump major version (1.0.0 -> 2.0.0)
$0 caddy 2.5.3 # Set specific version
Options:
--all <version-type> Bump all templates
Examples with --all:
$0 --all patch # Bump patch version for all templates
$0 --all 2.0.0 # Set all templates to version 2.0.0
EOF
exit 1
}
function get_current_version() {
local template="$1"
if [ -f "versions.json" ]; then
if which jq >/dev/null 2>&1; then
jq -r ".\"$template\" // \"1.0.0\"" versions.json
elif which python3 >/dev/null 2>&1; then
python3 -c "import json; data=json.load(open('versions.json')); print(data.get('$template', '1.0.0'))"
else
echo "1.0.0"
fi
else
echo "1.0.0"
fi
}
function bump_version() {
local current="$1"
local bump_type="$2"
# Split version into components
IFS='.' read -r major minor patch <<< "$current"
case "$bump_type" in
major)
echo "$((major + 1)).0.0"
;;
minor)
echo "${major}.$((minor + 1)).0"
;;
patch)
echo "${major}.${minor}.$((patch + 1))"
;;
*)
# Assume it's a specific version
echo "$bump_type"
;;
esac
}
function update_version() {
local template="$1"
local new_version="$2"
# Check if template exists
if [ ! -d "$template" ]; then
die "Template '$template' does not exist"
fi
# Update versions.json
if which jq >/dev/null 2>&1; then
# Use jq to update
jq ".\"$template\" = \"$new_version\"" versions.json > versions.json.tmp && mv versions.json.tmp versions.json
elif which python3 >/dev/null 2>&1; then
# Use python to update
python3 << EOF
import json
with open('versions.json', 'r') as f:
data = json.load(f)
data['$template'] = '$new_version'
with open('versions.json', 'w') as f:
json.dump(data, f, indent=2)
EOF
else
die "Neither jq nor python3 is available for JSON manipulation"
fi
info "Updated $template from $(get_current_version "$template") to $new_version"
}
# Parse arguments
if [ $# -lt 2 ]; then
usage
fi
if [ "$1" == "--all" ]; then
# Bump all templates
VERSION_TYPE="$2"
if [ -z "$VERSION_TYPE" ]; then
usage
fi
# Get all templates
TEMPLATES=$(find . -maxdepth 1 -type d ! -name ".*" ! -name "." | sed 's|^\./||' | grep -v ".gitea")
for TEMPLATE in $TEMPLATES; do
if [ ! -f "$TEMPLATE/install.sh" ]; then
continue
fi
CURRENT_VERSION=$(get_current_version "$TEMPLATE")
NEW_VERSION=$(bump_version "$CURRENT_VERSION" "$VERSION_TYPE")
update_version "$TEMPLATE" "$NEW_VERSION"
done
info "All templates updated"
else
# Bump specific template
TEMPLATE="$1"
VERSION_ARG="$2"
CURRENT_VERSION=$(get_current_version "$TEMPLATE")
NEW_VERSION=$(bump_version "$CURRENT_VERSION" "$VERSION_ARG")
update_version "$TEMPLATE" "$NEW_VERSION"
fi
# Show the updated versions
echo ""
echo "Current versions:"
if which jq >/dev/null 2>&1; then
jq . versions.json
else
cat versions.json
fi
echo ""
echo "To commit these changes:"
echo " git add versions.json"
echo " git commit -m 'Bump version(s)'"
echo ""
echo "After committing and pushing, the CI will automatically publish the updated templates."

78
detect-changes.sh Executable file
View File

@@ -0,0 +1,78 @@
#!/bin/bash
set -e
SCRIPT_DIR=$(dirname "$0")
cd "$SCRIPT_DIR"
function info() {
echo "INFO: $1" >&2
}
function get_last_version_tag() {
# Get the most recent tag that modified versions.json
git tag --sort=-version:refname | while read tag; do
if git diff --name-only "$tag" HEAD 2>/dev/null | grep -q "^versions.json$"; then
echo "$tag"
return
fi
done
# If no tag found, use the initial commit
echo ""
}
function detect_changed_templates() {
local base_ref="$1"
local changed_templates=""
if [ -z "$base_ref" ]; then
info "No previous version tag found, considering all templates as changed"
# Return all template directories
find . -maxdepth 1 -type d ! -name ".*" ! -name "." | sed 's|^\./||' | grep -v ".gitea" | sort
else
info "Comparing against $base_ref"
# Get list of changed files since the base ref
local changed_files=$(git diff --name-only "$base_ref" HEAD 2>/dev/null || echo "")
if [ -z "$changed_files" ]; then
info "No changes detected since $base_ref"
return
fi
# Check which templates have changes
for template_dir in $(find . -maxdepth 1 -type d ! -name ".*" ! -name "." | sed 's|^\./||' | grep -v ".gitea"); do
if echo "$changed_files" | grep -q "^${template_dir}/"; then
echo "$template_dir"
fi
done | sort | uniq
fi
}
# Main execution
if [ "$1" == "--json" ]; then
# Output as JSON array
last_tag=$(get_last_version_tag)
changed=$(detect_changed_templates "$last_tag")
if [ -z "$changed" ]; then
echo "[]"
else
echo -n "["
first=true
for template in $changed; do
if [ "$first" = true ]; then
first=false
else
echo -n ","
fi
echo -n "\"$template\""
done
echo "]"
fi
else
# Output as newline-separated list
last_tag=$(get_last_version_tag)
detect_changed_templates "$last_tag"
fi

0
gitea-runner-docker/logs.sh Normal file → Executable file
View File

0
gitea-runner-docker/ssh.sh Normal file → Executable file
View File

139
publish.sh Executable file
View File

@@ -0,0 +1,139 @@
#!/bin/bash
set -e
SCRIPT_DIR=$(dirname "$0")
cd "$SCRIPT_DIR"
function die() {
echo "ERROR: $1" >&2
exit 1
}
function info() {
echo "INFO: $1"
}
function get_version() {
local template="$1"
if [ -f "versions.json" ]; then
# Use jq if available, otherwise use python
if which jq >/dev/null 2>&1; then
jq -r ".\"$template\" // \"1.0.0\"" versions.json
elif which python3 >/dev/null 2>&1; then
python3 -c "import json; data=json.load(open('versions.json')); print(data.get('$template', '1.0.0'))"
else
echo "1.0.0"
fi
else
echo "1.0.0"
fi
}
# Parse arguments
PUBLISH_ALL=false
TEMPLATES_TO_PUBLISH=""
while [[ $# -gt 0 ]]; do
case $1 in
--all)
PUBLISH_ALL=true
shift
;;
--changed-only)
# Detect changed templates
if [ -x "./detect-changes.sh" ]; then
TEMPLATES_TO_PUBLISH=$(./detect-changes.sh)
if [ -z "$TEMPLATES_TO_PUBLISH" ]; then
info "No templates have changed, nothing to publish"
exit 0
fi
else
die "detect-changes.sh not found or not executable"
fi
shift
;;
*)
# Assume it's a specific template name
TEMPLATES_TO_PUBLISH="$TEMPLATES_TO_PUBLISH $1"
shift
;;
esac
done
# Check if SOS_WRITE_TOKEN is set
[[ -n $SOS_WRITE_TOKEN ]] || die "SOS_WRITE_TOKEN environment variable not set"
# Check if sos is installed
which sos >/dev/null || die "sos tool not found. Please install it first."
# If no specific templates specified and not --all, default to changed templates
if [ -z "$TEMPLATES_TO_PUBLISH" ] && [ "$PUBLISH_ALL" = false ]; then
if [ -x "./detect-changes.sh" ]; then
TEMPLATES_TO_PUBLISH=$(./detect-changes.sh)
if [ -z "$TEMPLATES_TO_PUBLISH" ]; then
info "No templates have changed, nothing to publish"
exit 0
fi
info "Publishing changed templates: $(echo $TEMPLATES_TO_PUBLISH | tr '\n' ' ')"
else
# Fallback to all templates if detect-changes.sh doesn't exist
PUBLISH_ALL=true
fi
fi
# Get list of templates to publish
if [ "$PUBLISH_ALL" = true ]; then
TEMPLATES_TO_PUBLISH=$(find . -maxdepth 1 -type d ! -name ".*" ! -name "." | sed 's|^\./||' | grep -v ".gitea")
info "Publishing all templates: $(echo $TEMPLATES_TO_PUBLISH | tr '\n' ' ')"
fi
if [ -z "$TEMPLATES_TO_PUBLISH" ]; then
die "No templates found to publish"
fi
# Create temporary directory for packaging
TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT
# Package and upload each template
for TEMPLATE in $TEMPLATES_TO_PUBLISH; do
if [ ! -f "$TEMPLATE/install.sh" ]; then
info "Skipping $TEMPLATE (no install.sh found)"
continue
fi
# Get the version for this template
VERSION=$(get_version "$TEMPLATE")
info "Packaging template: $TEMPLATE (version: $VERSION)"
# Create tarball of the template
TARBALL="$TMPDIR/${TEMPLATE}.tgz"
tar -czf "$TARBALL" -C . "$TEMPLATE"
# Calculate file size for info
SIZE=$(du -h "$TARBALL" | cut -f1)
info "Created $TEMPLATE.tgz ($SIZE)"
# Upload to templates.dropshell.app using sos
info "Uploading $TEMPLATE to templates.dropshell.app"
# Always upload with :latest tag
sos templates.dropshell.app "$TARBALL" "${TEMPLATE}:latest" || die "Failed to upload $TEMPLATE:latest"
info "Uploaded ${TEMPLATE}:latest"
# Also upload with specific version tag
sos templates.dropshell.app "$TARBALL" "${TEMPLATE}:${VERSION}" || die "Failed to upload $TEMPLATE:${VERSION}"
info "Uploaded ${TEMPLATE}:${VERSION}"
# If we have a major version, also tag with major version only (e.g., v1)
MAJOR_VERSION=$(echo "$VERSION" | cut -d. -f1)
if [ -n "$MAJOR_VERSION" ]; then
sos templates.dropshell.app "$TARBALL" "${TEMPLATE}:v${MAJOR_VERSION}" || die "Failed to upload $TEMPLATE:v${MAJOR_VERSION}"
info "Uploaded ${TEMPLATE}:v${MAJOR_VERSION}"
fi
info "Successfully uploaded $TEMPLATE"
done
info "All selected templates published successfully!"

145
test.sh Executable file
View File

@@ -0,0 +1,145 @@
#!/bin/bash
set -e
SCRIPT_DIR=$(dirname "$0")
cd "$SCRIPT_DIR"
function die() {
echo "ERROR: $1" >&2
exit 1
}
function info() {
echo "INFO: $1"
}
function success() {
echo -e "\033[32m✓ $1\033[0m"
}
function warning() {
echo -e "\033[33m⚠ $1\033[0m"
}
# Get list of template directories (exclude hidden directories)
TEMPLATES=$(find . -maxdepth 1 -type d ! -name ".*" ! -name "." | sed 's|^\./||' | grep -v ".gitea")
if [ -z "$TEMPLATES" ]; then
die "No templates found to test"
fi
info "Found templates to test: $(echo $TEMPLATES | tr '\n' ' ')"
FAILED_TESTS=""
SKIPPED_TESTS=""
# Run basic validation tests for each template
for TEMPLATE in $TEMPLATES; do
echo ""
info "Testing template: $TEMPLATE"
# Check if template directory exists
if [ ! -d "$TEMPLATE" ]; then
warning "Template directory $TEMPLATE does not exist, skipping"
SKIPPED_TESTS="$SKIPPED_TESTS $TEMPLATE"
continue
fi
# Check for required scripts
REQUIRED_SCRIPTS="install.sh uninstall.sh start.sh stop.sh status.sh"
MISSING_SCRIPTS=""
for SCRIPT in $REQUIRED_SCRIPTS; do
if [ ! -f "$TEMPLATE/$SCRIPT" ]; then
MISSING_SCRIPTS="$MISSING_SCRIPTS $SCRIPT"
fi
done
if [ -n "$MISSING_SCRIPTS" ]; then
echo " ERROR: Missing required scripts:$MISSING_SCRIPTS"
FAILED_TESTS="$FAILED_TESTS $TEMPLATE"
continue
fi
success "All required scripts present"
# Check if scripts are executable
NON_EXECUTABLE=""
for SCRIPT in $TEMPLATE/*.sh; do
if [ -f "$SCRIPT" ] && [ ! -x "$SCRIPT" ]; then
chmod +x "$SCRIPT"
info "Made $SCRIPT executable"
fi
done
# Check for config directory
if [ ! -d "$TEMPLATE/config" ]; then
echo " ERROR: Missing config directory"
FAILED_TESTS="$FAILED_TESTS $TEMPLATE"
continue
fi
success "Config directory exists"
# Check for service.env file
if [ ! -f "$TEMPLATE/config/service.env" ]; then
echo " ERROR: Missing config/service.env file"
FAILED_TESTS="$FAILED_TESTS $TEMPLATE"
continue
fi
success "service.env file exists"
# Validate shell scripts for basic syntax errors
SYNTAX_ERRORS=""
for SCRIPT in $TEMPLATE/*.sh; do
if [ -f "$SCRIPT" ]; then
if ! bash -n "$SCRIPT" 2>/dev/null; then
SCRIPT_NAME=$(basename "$SCRIPT")
SYNTAX_ERRORS="$SYNTAX_ERRORS $SCRIPT_NAME"
fi
fi
done
if [ -n "$SYNTAX_ERRORS" ]; then
echo " ERROR: Syntax errors in scripts:$SYNTAX_ERRORS"
FAILED_TESTS="$FAILED_TESTS $TEMPLATE"
continue
fi
success "All scripts pass syntax check"
# If we have the ds command available and we're in CI, we could run full tests
# For now, we'll skip integration tests in CI to avoid dependencies
if [ -n "$CI" ]; then
info "Skipping integration tests in CI environment"
else
if which ds >/dev/null 2>&1; then
info "ds command found, could run integration tests (skipping for safety)"
# Uncomment to enable integration tests:
# ./test_template.sh "$TEMPLATE" || FAILED_TESTS="$FAILED_TESTS $TEMPLATE"
else
info "ds command not found, skipping integration tests"
fi
fi
success "Template $TEMPLATE passed all tests"
done
echo ""
echo "========================================"
echo "Test Summary"
echo "========================================"
if [ -n "$SKIPPED_TESTS" ]; then
warning "Skipped templates:$SKIPPED_TESTS"
fi
if [ -n "$FAILED_TESTS" ]; then
echo -e "\033[31m✗ Failed templates:$FAILED_TESTS\033[0m"
exit 1
else
echo -e "\033[32m✓ All templates passed validation tests!\033[0m"
exit 0
fi

8
versions.json Normal file
View File

@@ -0,0 +1,8 @@
{
"caddy": "1.0.0",
"gitea-runner-docker": "1.0.0",
"simple-object-server": "1.0.0",
"squashkiwi": "1.0.0",
"static-website": "1.0.0",
"watchtower": "1.0.0"
}