controlled-release #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "controlled-release" | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to release (e.g., 3.5.0 or 3.5.0-beta.1)' | |
| required: true | |
| type: string | |
| concurrency: | |
| group: release-${{ github.event.inputs.version }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| packages: write | |
| issues: write | |
| jobs: | |
| prepare: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.vars.outputs.version }} | |
| tag: ${{ steps.vars.outputs.tag }} | |
| is_beta: ${{ steps.vars.outputs.is_beta }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set version variables | |
| id: vars | |
| run: | | |
| ver="${{ github.event.inputs.version }}" | |
| echo "version=$ver" >> $GITHUB_OUTPUT | |
| echo "tag=v$ver" >> $GITHUB_OUTPUT | |
| echo "is_beta=$([[ $ver == *-beta.* ]] && echo true || echo false)" >> $GITHUB_OUTPUT | |
| - name: Create and push tag | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag "${{ steps.vars.outputs.tag }}" | |
| git push origin "${{ steps.vars.outputs.tag }}" | |
| - name: Create verification issue | |
| run: | | |
| # Read template and replace placeholders | |
| TEMPLATE=$(cat .github/ISSUE_TEMPLATE/release-verification.md) | |
| TEMPLATE="${TEMPLATE//\{\{ COMMIT_SHA \}\}/${{ github.sha }}}" | |
| TEMPLATE="${TEMPLATE//\{\{ TAG \}\}/${{ steps.vars.outputs.tag }}}" | |
| TEMPLATE="${TEMPLATE//\{\{ RUN_URL \}\}/${{ github.run_url }}}" | |
| echo "$TEMPLATE" > /tmp/checklist.md | |
| gh issue create \ | |
| --title "Verify ${{ steps.vars.outputs.tag }}" \ | |
| --label "release-verification" \ | |
| --body-file /tmp/checklist.md \ | |
| --assignee "$GITHUB_ACTOR" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| build-and-gate: | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| environment: release-gate | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.prepare.outputs.tag }} | |
| - name: Set up JDK 25 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '25' | |
| distribution: 'temurin' | |
| cache: maven | |
| - name: Install dependencies for acknowledgments script | |
| run: sudo apt-get update && sudo apt-get install -y jq curl | |
| - name: Generate acknowledgments data | |
| run: | | |
| chmod +x scripts/generate-acknowledgments.sh | |
| ./scripts/generate-acknowledgments.sh | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build | |
| run: mvn verify -DskipTests | |
| - name: Create bundle | |
| run: mkdir staging && cp target/*.jar staging | |
| - name: Upload packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Package | |
| path: staging | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_HUB_USERNAME }} | |
| password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Set up QEMU & Buildx | |
| uses: docker/setup-qemu-action@v3 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Docker meta for reitti | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| context: 'git' | |
| images: | | |
| dedicatedcode/reitti | |
| ghcr.io/${{ github.repository }} | |
| tags: | | |
| type=raw,value=latest,enable=${{ !contains(github.ref, '-beta') && github.ref_type == 'tag' }} | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}},enable=${{ !contains(github.ref, '-beta') }} | |
| type=semver,pattern={{major}},enable=${{ !contains(github.ref, '-beta') }} | |
| - name: Build and push reitti image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| platforms: linux/amd64,linux/arm64 | |
| context: . | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| - name: Docker meta for tile-cache | |
| id: meta-tile-cache | |
| uses: docker/metadata-action@v5 | |
| with: | |
| context: 'git' | |
| images: | | |
| dedicatedcode/reitti-tile-cache | |
| ghcr.io/${{ github.repository }}-tile-cache | |
| tags: | | |
| type=raw,value=latest,enable=${{ !contains(github.ref, '-beta') && github.ref_type == 'tag' }} | |
| type=semver,pattern={{version}} | |
| type=semver,pattern={{major}}.{{minor}},enable=${{ !contains(github.ref, '-beta') }} | |
| type=semver,pattern={{major}},enable=${{ !contains(github.ref, '-beta') }} | |
| - name: Build and push tile-cache image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| platforms: linux/amd64,linux/arm64 | |
| context: ./docker/tiles-cache | |
| push: true | |
| tags: ${{ steps.meta-tile-cache.outputs.tags }} | |
| labels: ${{ steps.meta-tile-cache.outputs.labels }} | |
| publish-release: | |
| needs: [prepare, build-and-gate] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ needs.prepare.outputs.tag }} | |
| - name: Download artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: Package | |
| - name: Create & publish GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.prepare.outputs.tag }} | |
| name: Release ${{ needs.prepare.outputs.tag }} | |
| generate_release_notes: true | |
| prerelease: ${{ needs.prepare.outputs.is_beta == 'true' }} | |
| make_latest: ${{ needs.prepare.outputs.is_beta == 'false' }} | |
| files: "*.jar" | |
| - name: Close verification issue | |
| run: | | |
| ISSUE=$(gh issue list --label "release-verification" --state open --limit 1 --json number -q '.[0].number') | |
| [ -n "$ISSUE" ] && gh issue close "$ISSUE" --comment "Released via workflow run #${{ github.run_id }}" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| cleanup-on-failure: | |
| needs: [prepare, build-and-gate] | |
| if: failure() || cancelled() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Delete tag if verification cancelled/failed | |
| run: | | |
| gh api -X DELETE repos/${{ github.repository }}/git/refs/tags/${{ needs.prepare.outputs.tag }} || true | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Close verification issue on cancel/fail | |
| run: | | |
| ISSUE=$(gh issue list --label "release-verification" --state open --limit 1 --json number -q '.[0].number') | |
| [ -n "$ISSUE" ] && gh issue close "$ISSUE" --comment "Release cancelled or failed. Workflow run #${{ github.run_id }}" | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |