From 81a9391fcad5151325daee9e1781d5915d8b6eda Mon Sep 17 00:00:00 2001 From: Gavin Didrichsen Date: Fri, 1 Aug 2025 13:08:11 +0100 Subject: [PATCH 1/3] update dummy.txt --- dummy.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 dummy.txt diff --git a/dummy.txt b/dummy.txt new file mode 100644 index 0000000..230463d --- /dev/null +++ b/dummy.txt @@ -0,0 +1 @@ +Fri Aug 1 13:08:11 BST 2025 From bd2172906779e61ea3b7b08dfb25fc50b207ff00 Mon Sep 17 00:00:00 2001 From: Gavin Didrichsen Date: Fri, 1 Aug 2025 13:33:14 +0100 Subject: [PATCH 2/3] remove dummy.txt --- dummy.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 dummy.txt diff --git a/dummy.txt b/dummy.txt deleted file mode 100644 index 230463d..0000000 --- a/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Fri Aug 1 13:08:11 BST 2025 From a56b1bcb2abe0447a1d1867cf78f1f8691b4c2d9 Mon Sep 17 00:00:00 2001 From: Gavin Didrichsen Date: Fri, 1 Aug 2025 14:16:38 +0100 Subject: [PATCH 3/3] feat: implement test branch strategy for GitHub Pages deployment - Fix GitHub Actions permissions issue with job-level overrides - Add test-gh-pages-publish branch for safe deployment testing - Implement DRY DEPLOY_CONDITION for maintainable workflow - Create ADR 0007 documenting test branch strategy with Obsidian tags - Enable testing of Pages deployment without affecting production Resolves the id-token: write permission error that occurred after merging PRs with Pages deployment changes. Signed-off-by: Gavin Didrichsen --- .github/workflows/ci.yml | 31 ++++--- docs/README.md | 1 + ...nch-for-github-pages-deployment-testing.md | 80 +++++++++++++++++++ 3 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 docs/exp/adr/0007-use-dedicated-test-branch-for-github-pages-deployment-testing.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3271a2..6623910 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,19 +2,24 @@ name: CI on: push: - branches: [ main, master ] + branches: [ + main, + master, + test-gh-pages-publish # Special branch for testing GitHub Pages deployment + ] pull_request: branches: [ main, master ] -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +# Global permissions apply to all jobs by default. Individual jobs that require +# additional permissions must define their own permissions block, which completely +# overrides (not merges with) these global permissions. permissions: contents: read - pages: write - id-token: write jobs: test: runs-on: ubuntu-latest + # No additional permissions needed - inherits contents: read strategy: matrix: ruby-version: ['3.2'] @@ -36,6 +41,7 @@ jobs: lint: runs-on: ubuntu-latest + # No additional permissions needed - inherits contents: read steps: - uses: actions/checkout@v4 @@ -53,8 +59,15 @@ jobs: coverage: runs-on: ubuntu-latest permissions: - contents: write - pull-requests: write + contents: read # Required for actions/checkout + pull-requests: write # Required for commenting on PRs + pages: write # Required for GitHub Pages deployment + id-token: write # Required for GitHub Pages deployment (OIDC) + env: + # DEPLOY_CONDITION controls when GitHub Pages deployment occurs. + # Production: main, master branches deploy automatically + # Testing: test-gh-pages-publish branch allows safe deployment testing without affecting production + DEPLOY_CONDITION: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/test-gh-pages-publish' }} steps: - uses: actions/checkout@v4 @@ -78,17 +91,17 @@ jobs: retention-days: 30 - name: Setup Pages - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + if: env.DEPLOY_CONDITION == 'true' uses: actions/configure-pages@v4 - name: Upload Pages artifact - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + if: env.DEPLOY_CONDITION == 'true' uses: actions/upload-pages-artifact@v3 with: path: coverage - name: Deploy to GitHub Pages - if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' + if: env.DEPLOY_CONDITION == 'true' uses: actions/deploy-pages@v4 with: path: coverage diff --git a/docs/README.md b/docs/README.md index 822034d..d2728a5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -35,4 +35,5 @@ * [ADR-0004](exp/adr/0004-store-sample-lock-files-in-spec-fixtures.md) - Store Sample Lock Files in spec/fixtures * [ADR-0005](exp/adr/0005-use-shields-io-for-coverage-badge.md) - Use shields.io for coverage badge * [ADR-0006](exp/adr/0006-collect-additional-gem-metadata-from-bundle-info.md) - Collect additional gem metadata from bundle info +* [ADR-0007](exp/adr/0007-use-dedicated-test-branch-for-github-pages-deployment-testing.md) - Use dedicated test branch for GitHub Pages deployment testing diff --git a/docs/exp/adr/0007-use-dedicated-test-branch-for-github-pages-deployment-testing.md b/docs/exp/adr/0007-use-dedicated-test-branch-for-github-pages-deployment-testing.md new file mode 100644 index 0000000..9df704f --- /dev/null +++ b/docs/exp/adr/0007-use-dedicated-test-branch-for-github-pages-deployment-testing.md @@ -0,0 +1,80 @@ +--- +tags: + - best-practice + - github + - ci-cd + - deployment + - testing + - permissions + - github-actions +date: 2025-08-01 +status: accepted +--- + +# 7. Use dedicated test branch for GitHub Pages deployment testing + +Date: 2025-08-01 + +## Status + +Accepted + +## Context + +We experienced a GitHub Actions failure after merging a PR that added GitHub Pages deployment functionality. The failure occurred because the coverage job lacked the required `id-token: write` permission for Pages deployment. This failure only manifested after merging to the main branch, not during PR testing, because: + +1. Pages deployment steps are conditionally executed only on main/master branches +2. Job-level permissions completely override (not merge with) global permissions in GitHub Actions +3. The coverage job defined its own permissions block without including the Pages-required permissions + +This created a testing gap: we couldn't validate the Pages deployment functionality before merging changes to production branches. We needed a way to test Pages deployment changes safely without: + +- Affecting production deployments +- Requiring temporary modifications to workflow files +- Waiting until after merge to discover permission issues + +## Decision + +We will use a dedicated test branch named `test-gh-pages-publish` that: + +1. **Triggers the CI workflow** - Added to the `on.push.branches` list +2. **Enables Pages deployment** - Included in the `DEPLOY_CONDITION` environment variable +3. **Provides clear intent** - The branch name explicitly indicates its testing purpose +4. **Requires no cleanup** - Can remain in the workflow permanently without affecting production + +The implementation uses a DRY approach with an environment variable `DEPLOY_CONDITION` that controls all three Pages deployment steps, making it easy to maintain and modify. + +## Consequences + +### What becomes easier + +- **Safe testing** of Pages deployment changes before merging to main +- **Validation** of permissions and deployment configuration +- **Debugging** deployment issues in isolation +- **Self-documenting** workflows with clear testing intentions +- **Reusable testing** - the test branch can be used whenever needed + +### What becomes more difficult + +- **Slightly more complex** workflow configuration (minimal impact) +- **Additional branch** to manage (but lightweight since it's just for testing) +- **Potential confusion** for new contributors (mitigated by clear naming and comments) + +### Risk mitigation + +- Clear naming convention prevents accidental production use +- Comments in workflow explain the purpose +- Test deployments won't affect main branch coverage reports +- Can be easily removed if testing approach changes + +### Alternative approaches considered + +1. **Temporary development branch inclusion** - Rejected due to need for manual cleanup +2. **Using "master" branch** - Rejected due to production confusion +3. **Manual testing in forks** - Rejected due to complexity and permissions differences + +## Related Topics + +- **Best Practices**: GitHub Actions, CI/CD, Deployment +- **Technologies**: GitHub Pages, Ruby, Testing +- **Context**: Release Process, Permissions Management