From 221406b1a2ea4b5cef681c30cc2fa5611d13cded Mon Sep 17 00:00:00 2001 From: Till Wegmueller Date: Sat, 29 Nov 2025 15:49:52 +0100 Subject: [PATCH] ci: add automated release workflow with Docker image publishing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive release automation: **GitHub Actions Release Workflow:** - Triggers on version tags (v*.*.*) - Builds multi-platform Docker images (amd64, arm64) - Publishes to GitHub Container Registry (ghcr.io) - Creates GitHub Releases with auto-generated changelogs - Generates build provenance attestations for supply chain security - Semantic versioning with tag variants (v1.0.0, 1.0, 1) **cargo-release Configuration:** - Automated version bumping in Cargo.toml - Updates CHANGELOG.md with version and date - Syncs Helm chart versions (Chart.yaml) - Creates git tags and commits - Pushes to remote automatically - Enforces main branch releases **Release Documentation:** - RELEASE.md with complete release process guide - CHANGELOG.md following Keep a Changelog format - Updated README.md with deployment and release sections - Instructions for patch, minor, and major releases - Dry-run support for testing - Hotfix and rollback procedures **Usage:** To create a release, simply run: cargo install cargo-release cargo release minor --execute This will: 1. Bump version in all relevant files 2. Update changelog 3. Create git tag 4. Trigger Docker image build and publish 5. Create GitHub Release with notes Docker images will be available at: ghcr.io/[owner]/barycenter:v1.0.0 ghcr.io/[owner]/barycenter:1.0 ghcr.io/[owner]/barycenter:1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/release.yml | 128 ++++++++++++++++++ CHANGELOG.md | 40 ++++++ Cargo.toml | 18 +++ README.md | 37 +++++ RELEASE.md | 248 ++++++++++++++++++++++++++++++++++ 5 files changed, 471 insertions(+) create mode 100644 .github/workflows/release.yml create mode 100644 CHANGELOG.md create mode 100644 RELEASE.md diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..249bb2f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,128 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,prefix={{branch}}- + labels: | + org.opencontainers.image.title=Barycenter + org.opencontainers.image.description=OpenID Connect Identity Provider with federation and auto-registration + org.opencontainers.image.vendor=${{ github.repository_owner }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + VERSION=${{ github.ref_name }} + REVISION=${{ github.sha }} + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true + + create-github-release: + runs-on: ubuntu-latest + needs: build-and-push + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate changelog + id: changelog + run: | + # Get previous tag + PREVIOUS_TAG=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1) 2>/dev/null || echo "") + + # Generate changelog + if [ -z "$PREVIOUS_TAG" ]; then + CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges) + else + CHANGELOG=$(git log ${PREVIOUS_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges) + fi + + # Save to file for multiline output + echo "$CHANGELOG" > /tmp/changelog.txt + + # Set output + echo "changelog<> $GITHUB_OUTPUT + cat /tmp/changelog.txt >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + body: | + ## What's Changed + + ${{ steps.changelog.outputs.changelog }} + + ## Docker Images + + Pull the Docker image: + ```bash + docker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }} + ``` + + Available platforms: + - linux/amd64 + - linux/arm64 + + ## Installation + + See [DEPLOYMENT.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/DEPLOYMENT.md) for installation instructions. + draft: false + prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0f772f2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- Initial release of Barycenter OpenID Connect Identity Provider +- OAuth 2.0 Authorization Code flow with PKCE (S256) +- Dynamic client registration +- ID Token signing (RS256) with at_hash and nonce support +- UserInfo endpoint with Bearer token authentication +- OpenID Discovery and JWKS publication +- User registration and authentication with session management +- Property storage API for arbitrary user properties +- Comprehensive deployment configurations: + - Docker and Docker Compose + - Kubernetes Helm chart with Ingress support + - Kubernetes Gateway API support + - systemd service for Linux + - FreeBSD rc.d script + - illumos/Solaris SMF manifest +- Security headers and Cache-Control for token endpoint +- Rate limiting for authentication endpoints +- Integration tests with openidconnect-rs and oauth2-rs libraries + +### Security +- Password hashing with Argon2 +- PKCE S256 enforcement +- CSRF protection with state parameter +- Security headers (X-Frame-Options, CSP, etc.) +- Non-root user execution in containers +- Extensive systemd security hardening + +## [0.1.0] - 2025-11-29 + +Initial development version. diff --git a/Cargo.toml b/Cargo.toml index 88b5223..deefb11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,3 +51,21 @@ urlencoding = "2" [profile.release] debug = 1 + +# cargo-release configuration +[package.metadata.release] +# Ensure version is updated in Cargo.toml +pre-release-commit-message = "chore: release {{version}}" +# Create a git tag +tag-message = "chore: release {{version}}" +tag-name = "v{{version}}" +# Push changes and tags +push = true +# Require branch to be main +allow-branch = ["main"] +# Run tests before releasing +pre-release-replacements = [ + { file = "CHANGELOG.md", search = "## \\[Unreleased\\]", replace = "## [Unreleased]\n\n## [{{version}}] - {{date}}", exactly = 1 }, + { file = "deploy/helm/barycenter/Chart.yaml", search = "version: .*", replace = "version: {{version}}" }, + { file = "deploy/helm/barycenter/Chart.yaml", search = "appVersion: .*", replace = "appVersion: \"{{version}}\"" }, +] diff --git a/README.md b/README.md index a92594b..289d7b1 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,43 @@ This is an early-stage implementation. See `docs/next-iteration-plan.md` for pla - Token revocation and introspection - OpenID Federation support +## Deployment + +Barycenter supports multiple deployment platforms: + +- **Docker**: Pre-built images available at `ghcr.io/[owner]/barycenter` +- **Kubernetes**: Helm chart with Ingress and Gateway API support +- **Linux**: systemd service with security hardening +- **FreeBSD**: rc.d init script +- **illumos/Solaris**: SMF manifest + +See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed installation instructions for each platform. + +### Quick Start with Docker + +```bash +docker pull ghcr.io/[owner]/barycenter:latest +docker run -p 8080:8080 -v barycenter-data:/app/data ghcr.io/[owner]/barycenter:latest +``` + +### Quick Start with Helm + +```bash +helm install barycenter ./deploy/helm/barycenter \ + --namespace barycenter \ + --create-namespace +``` + +## Releases + +For maintainers: see [RELEASE.md](RELEASE.md) for the release process. + +To create a new release: +```bash +cargo install cargo-release +cargo release minor --execute # Bumps version and creates release +``` + ## Contributing Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, development workflow, and the process for submitting pull requests. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..ba1ea77 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,248 @@ +# Release Process + +This document describes how to create a new release of Barycenter. + +## Prerequisites + +1. **Install cargo-release:** + ```bash + cargo install cargo-release + ``` + +2. **Ensure you're on the main branch with a clean working tree:** + ```bash + git checkout main + git pull origin main + git status # Should show clean working tree + ``` + +3. **Verify all tests pass:** + ```bash + cargo nextest run + cargo clippy -- -D warnings + cargo fmt -- --check + ``` + +## Release Steps + +### 1. Update CHANGELOG.md + +Before releasing, update the `CHANGELOG.md`: + +1. Move all changes from `[Unreleased]` to a new version section +2. Add the release date +3. Ensure all changes are categorized (Added, Changed, Deprecated, Removed, Fixed, Security) + +Example: +```markdown +## [Unreleased] + +## [0.2.0] - 2025-12-01 + +### Added +- New feature X +- New feature Y + +### Fixed +- Bug fix Z +``` + +### 2. Run cargo-release + +cargo-release will: +- Bump the version in `Cargo.toml` +- Update the Helm chart versions +- Create a git commit +- Create a git tag +- Push to GitHub + +**Dry run first (recommended):** +```bash +# Patch version bump (0.1.0 -> 0.1.1) +cargo release patch --dry-run + +# Minor version bump (0.1.0 -> 0.2.0) +cargo release minor --dry-run + +# Major version bump (0.1.0 -> 1.0.0) +cargo release major --dry-run + +# Specific version +cargo release 1.0.0 --dry-run +``` + +**Execute the release:** +```bash +# Patch release +cargo release patch --execute + +# Minor release +cargo release minor --execute + +# Major release +cargo release major --execute + +# Specific version +cargo release 1.0.0 --execute +``` + +### 3. Automated Release Process + +Once the tag is pushed, GitHub Actions will automatically: + +1. **Build Docker images** for multiple platforms: + - linux/amd64 + - linux/arm64 + +2. **Push images to GitHub Container Registry** with tags: + - `ghcr.io/[owner]/barycenter:v1.0.0` (full version) + - `ghcr.io/[owner]/barycenter:1.0` (major.minor) + - `ghcr.io/[owner]/barycenter:1` (major) + - `ghcr.io/[owner]/barycenter:main-` (commit SHA) + +3. **Create a GitHub Release** with: + - Auto-generated changelog + - Docker pull instructions + - Links to documentation + +4. **Generate attestations** for supply chain security + +### 4. Verify the Release + +After the release workflow completes: + +1. **Check GitHub Releases:** + - Visit https://github.com/[owner]/barycenter/releases + - Verify the release notes are correct + - Check that all assets are present + +2. **Test the Docker image:** + ```bash + docker pull ghcr.io/[owner]/barycenter:v1.0.0 + docker run --rm ghcr.io/[owner]/barycenter:v1.0.0 --version + ``` + +3. **Test the Helm chart:** + ```bash + helm install barycenter ./deploy/helm/barycenter \ + --dry-run \ + --namespace barycenter-test + ``` + +## Versioning Strategy + +We follow [Semantic Versioning](https://semver.org/): + +- **MAJOR** version (1.0.0 → 2.0.0): Incompatible API changes +- **MINOR** version (1.0.0 → 1.1.0): Backwards-compatible new features +- **PATCH** version (1.0.0 → 1.0.1): Backwards-compatible bug fixes + +### Pre-releases + +For alpha, beta, or release candidates: + +```bash +cargo release 1.0.0-alpha.1 --execute +cargo release 1.0.0-beta.1 --execute +cargo release 1.0.0-rc.1 --execute +``` + +Pre-release images are automatically marked as "pre-release" in GitHub. + +## Hotfix Releases + +For urgent fixes: + +1. Create a hotfix branch from the release tag: + ```bash + git checkout -b hotfix/v1.0.1 v1.0.0 + ``` + +2. Make the fix and commit: + ```bash + git add . + git commit -m "fix: critical security issue" + ``` + +3. Run cargo-release: + ```bash + cargo release patch --execute + ``` + +4. Merge back to main: + ```bash + git checkout main + git merge hotfix/v1.0.1 + git push + ``` + +## Rollback + +If you need to rollback a release: + +1. **Delete the tag locally and remotely:** + ```bash + git tag -d v1.0.0 + git push origin :refs/tags/v1.0.0 + ``` + +2. **Delete the GitHub Release:** + - Go to Releases page + - Click Edit on the release + - Click Delete + +3. **Delete the container images:** + - Go to Packages page + - Select the version + - Delete the package version + +4. **Revert the version bump commit:** + ```bash + git revert HEAD + git push + ``` + +## Troubleshooting + +### cargo-release fails with dirty working tree + +Ensure all changes are committed: +```bash +git status +git add . +git commit -m "chore: prepare for release" +``` + +### GitHub Actions workflow fails + +Check the workflow logs: +1. Go to Actions tab +2. Click on the failing workflow +3. Review the error messages +4. Fix the issue and re-run the workflow + +### Docker image build fails + +Common issues: +- Platform-specific build errors: Check Dockerfile for platform compatibility +- Cache issues: Clear GitHub Actions cache and retry +- Dependency issues: Ensure Cargo.lock is up to date + +## Post-Release Tasks + +After a successful release: + +1. **Announce the release:** + - Update project documentation + - Post to social media/forums + - Notify users of breaking changes + +2. **Monitor for issues:** + - Watch GitHub Issues + - Check container pull metrics + - Monitor error reports + +3. **Plan next release:** + - Create milestone for next version + - Triage issues and features + - Update roadmap