chore: fix release and updater script (#57) #11
Workflow file for this run
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: publish-docker | |
| # Builds, tests, and publishes the socket-basics image to GHCR and Docker Hub. | |
| # | |
| # Flow: resolve-version → build-test-push → create-release | |
| # | |
| # Tag convention: | |
| # v2.0.0 — immutable exact release (floating major tags intentionally not published) | |
| # See docs/github-action.md → "Pinning strategies" for the full rationale. | |
| # | |
| # Required repository secrets: | |
| # DOCKERHUB_USERNAME — Docker Hub account name | |
| # DOCKERHUB_TOKEN — Docker Hub access token (read/write) | |
| on: | |
| push: | |
| tags: | |
| - 'v[0-9]+.[0-9]+.[0-9]+' | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Full git tag to publish (e.g. v2.0.0 for new releases, 1.1.3 for old). Must exist in the repo." | |
| required: true | |
| # Default: deny everything. Each job below grants only what it needs. | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: publish-docker-${{ github.ref }} | |
| cancel-in-progress: false # never cancel an in-flight publish | |
| jobs: | |
| # ── Job 1: Resolve version ───────────────────────────────────────────────── | |
| # Computes a clean semver string (no v prefix) consumed by downstream jobs. | |
| resolve-version: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.version.outputs.clean }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref }} | |
| - name: 🏷️ Resolve version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| CLEAN="${{ inputs.tag }}" # full tag as provided (e.g. 1.1.3 or v2.0.0) | |
| else | |
| CLEAN="${{ github.ref_name }}" # e.g. v2.0.0 | |
| fi | |
| CLEAN="${CLEAN#v}" # strip leading v if present → 2.0.0 or 1.1.3 | |
| echo "clean=$CLEAN" >> "$GITHUB_OUTPUT" | |
| # ── Job 2: Build → test → push ───────────────────────────────────────────── | |
| # Delegates all Docker steps to the reusable _docker-pipeline workflow. | |
| build-test-push: | |
| name: publish (socket-basics) | |
| needs: resolve-version | |
| permissions: | |
| contents: read | |
| packages: write # push images to GHCR | |
| uses: ./.github/workflows/_docker-pipeline.yml | |
| with: | |
| name: socket-basics | |
| dockerfile: Dockerfile | |
| context: . | |
| check_set: main | |
| push: true | |
| tag_push: ${{ github.ref_type == 'tag' }} | |
| version: ${{ needs.resolve-version.outputs.version }} | |
| secrets: inherit | |
| # ── Job 3: Create GitHub release + update CHANGELOG ──────────────────────── | |
| # Runs once after the image is successfully pushed (not for workflow_dispatch | |
| # re-publishes — those don't create new releases). | |
| # Generates categorised release notes from merged PR labels (.github/release.yml), | |
| # creates the GitHub Release, then commits the CHANGELOG update back to main. | |
| create-release: | |
| needs: [resolve-version, build-test-push] | |
| if: github.ref_type == 'tag' | |
| permissions: | |
| contents: write # create GitHub release + commit CHANGELOG back to main | |
| runs-on: ubuntu-latest | |
| env: | |
| VERSION: ${{ needs.resolve-version.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: main | |
| fetch-depth: 0 | |
| - name: 🤖 Generate socket-release-bot token | |
| id: bot | |
| uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 | |
| with: | |
| app-id: ${{ secrets.GH_BOT_APP_ID }} | |
| private-key: ${{ secrets.GH_BOT_APP_PEM_FILE }} | |
| owner: SocketDev | |
| repositories: socket-basics | |
| - name: 📝 Create GitHub release with auto-generated notes | |
| run: | | |
| gh release create "${{ github.ref_name }}" \ | |
| --title "${{ github.ref_name }}" \ | |
| --generate-notes \ | |
| --verify-tag \ | |
| || echo "Release already exists (re-run scenario) — skipping creation" | |
| env: | |
| GH_TOKEN: ${{ steps.bot.outputs.token }} | |
| - name: 📋 Update CHANGELOG.md | |
| run: | | |
| NOTES=$(gh release view "${{ github.ref_name }}" --json body --jq .body) | |
| DATE=$(date +%Y-%m-%d) | |
| echo "$NOTES" | python scripts/update_changelog.py \ | |
| --version "$VERSION" \ | |
| --date "$DATE" | |
| env: | |
| GH_TOKEN: ${{ steps.bot.outputs.token }} | |
| - name: 🔀 Commit CHANGELOG + action.yml back to main | |
| run: | | |
| git config user.name "socket-release-bot[bot]" | |
| git config user.email "socket-release-bot[bot]@users.noreply.github.com" | |
| git remote set-url origin "https://x-access-token:${{ steps.bot.outputs.token }}@github.com/SocketDev/socket-basics.git" | |
| # Auto-update action.yml image ref to the new version. | |
| # No-op if action.yml still uses `image: "Dockerfile"` (handles the | |
| # chicken-and-egg on the initial v2.0.0 release). | |
| if grep -q 'docker://ghcr.io/socketdev/socket-basics:' action.yml; then | |
| sed -i "s|docker://ghcr.io/socketdev/socket-basics:[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*|docker://ghcr.io/socketdev/socket-basics:${VERSION}|" action.yml | |
| echo "Updated action.yml image ref to ${VERSION}" | |
| else | |
| echo "action.yml not yet using pre-built image — skipping version update" | |
| fi | |
| git add CHANGELOG.md action.yml | |
| git diff --cached --quiet || git commit -m "chore: release ${{ github.ref_name }} — update CHANGELOG and action.yml [skip ci]" | |
| git push origin HEAD:main |