diff --git a/.gitea/workflows/test-and-publish.yaml b/.gitea/workflows/test-and-publish.yaml new file mode 100644 index 0000000..ffeda9f --- /dev/null +++ b/.gitea/workflows/test-and-publish.yaml @@ -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." \ No newline at end of file diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..7fa6e30 --- /dev/null +++ b/DEVELOPMENT.md @@ -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 + ``` +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 \ No newline at end of file diff --git a/bump-version.sh b/bump-version.sh new file mode 100755 index 0000000..3dd7d24 --- /dev/null +++ b/bump-version.sh @@ -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