Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand All @@ -36,6 +41,7 @@ jobs:

lint:
runs-on: ubuntu-latest
# No additional permissions needed - inherits contents: read
steps:
- uses: actions/checkout@v4

Expand All @@ -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

Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<!-- adrlogstop -->
Original file line number Diff line number Diff line change
@@ -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