Skip to content

ci: GitHub Pages deploy pipeline - preview, staging and production#20

Merged
hiranyasemindi merged 5 commits into
masterfrom
feat/github-pages-deploy
Jun 17, 2026
Merged

ci: GitHub Pages deploy pipeline - preview, staging and production#20
hiranyasemindi merged 5 commits into
masterfrom
feat/github-pages-deploy

Conversation

@iamvirul

@iamvirul iamvirul commented Jun 17, 2026

Copy link
Copy Markdown
Member

Summary

Sets up a full GitHub Pages deployment pipeline with three environments: PR preview, staging, and production.

Type

  • Chore

Changes

  • deploy-preview.yml - triggers on every PR commit, deploys to /bms/pr-{N}/, posts a live URL comment on the PR, cleans up the preview directory when the PR is closed
  • deploy-staging.yml - triggers automatically when a PR merges to master, deploys to /bms/staging/, also has a manual workflow_dispatch fallback
  • deploy-prod.yml - triggers automatically when staging completes successfully, deploys to /bms/ (root), also has a manual workflow_dispatch fallback

Pipeline flow:

PR commit -> preview auto-deploys
PR merged -> staging auto-deploys
Staging passes -> production auto-deploys

All three environments are configured in GitHub Settings > Environments (staging has 1 protection rule already set).

Test plan

  • Workflow YAML syntax validated
  • No regressions in related screens

Related issues

Closes - GitHub Pages deployment setup

Summary by CodeRabbit

Summary by CodeRabbit

  • Chores
    • Added automated deployment workflows for preview, staging, and production environments
    • PR previews now automatically build and deploy, with live preview links posted as comments
    • Staging environment automatically deploys on updates to the main branch (and supports manual runs)
    • Production environment automatically deploys after a successful staging deployment, with a manual fallback

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 66383d29-2c37-4fad-b78e-d2096c52fe64

📥 Commits

Reviewing files that changed from the base of the PR and between ebd0d28 and aef1ac2.

📒 Files selected for processing (3)
  • .github/workflows/deploy-preview.yml
  • .github/workflows/deploy-prod.yml
  • .github/workflows/deploy-staging.yml
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/workflows/deploy-staging.yml
  • .github/workflows/deploy-preview.yml
  • .github/workflows/deploy-prod.yml

📝 Walkthrough

Walkthrough

Three GitHub Actions workflows are added to establish a complete deployment pipeline: a PR preview workflow that builds and publishes per-PR Flutter web deployments to gh-pages, posts or updates a bot comment with the preview URL, and cleans up on PR close; a staging workflow triggered on pushes to master that publishes to a staging GitHub Pages destination; and a production workflow that auto-triggers after staging succeeds on master, promoting the same commit to the production GitHub Pages environment.

Changes

Flutter Web Deployment Workflows

Layer / File(s) Summary
PR Preview workflow: deploy, comment, and cleanup
.github/workflows/deploy-preview.yml
Adds the PR Preview workflow with a deploy job that builds Flutter web with a PR-specific base-href and publishes to gh-pages under pr-<number>, a GitHub Script step that creates or updates a bot comment containing the preview URL and short SHA, and a cleanup job that removes the preview directory when the PR is closed.
Staging deployment workflow
.github/workflows/deploy-staging.yml
Adds the Deploy to Staging workflow triggered on push to master (and workflow_dispatch), which runs build_runner, builds with --base-href /bms/staging/, and publishes ./build/web to the staging GitHub Pages destination with cancellation concurrency.
Production deployment workflow chained from staging
.github/workflows/deploy-prod.yml
Adds the production workflow that triggers on successful completion of Deploy to Staging on master (or manually), checks out the staging run's head_sha, builds with --base-href /bms/, and publishes to GitHub Pages targeting the production environment.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hoppy the rabbit builds the web with flair,
Staging and preview fly through the air!
A PR gets a comment, a link all its own,
When merged, production is carefully sown.
With gh-pages as pasture, the bunny hops free—
Three workflows deployed, as smooth as can be! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: establishing a GitHub Pages deployment pipeline with three environments (preview, staging, production).
Description check ✅ Passed The description follows the template structure with all required sections completed: Summary, Type (Chore checked), Changes (clearly listed), Test plan (items checked), and Related issues. Content is detailed and comprehensive.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/github-pages-deploy

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Preview deployed

URL https://getbms.github.io/bms/pr-20/
Commit d583d76
Status Live

Updates automatically on every push.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
.github/workflows/deploy-preview.yml (2)

25-25: ⚡ Quick win

Add persist-credentials: false to harden checkout security.

The checkout action persists the GitHub token in .git/config by default, which could be exploited if malicious code runs in subsequent steps. Since the peaceiris/actions-gh-pages action receives its own github_token parameter (line 41) and doesn't rely on the persisted credentials, setting persist-credentials: false follows defense-in-depth principles without breaking functionality.

🔒 Proposed security hardening
     steps:
       - uses: actions/checkout@v4
+        with:
+          persist-credentials: false
 
       - uses: subosito/flutter-action@v2
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy-preview.yml at line 25, The `actions/checkout@v4`
action currently persists the GitHub token in `.git/config` by default, creating
a security risk if malicious code executes in subsequent workflow steps. Add the
`persist-credentials: false` parameter to the checkout action configuration to
disable this behavior. Since the `peaceiris/actions-gh-pages` action on line 41
provides its own `github_token` parameter, this change will harden security
without affecting the workflow's functionality.

Source: Linters/SAST tools


7-9: ⚡ Quick win

Consider scoping permissions per job for least-privilege security.

Currently, both contents: write and pull-requests: write are granted at the workflow level, but only the deploy job needs both permissions—the cleanup job requires only contents: write. Scoping permissions per job reduces the attack surface.

🔒 Proposed refactor to scope permissions per job

Remove the workflow-level permissions and scope them per job:

-permissions:
-  contents: write
-  pull-requests: write
-
 concurrency:
   group: pr-preview-${{ github.event.number }}
   cancel-in-progress: true
 
 jobs:
   deploy:
     if: github.event.action != 'closed'
     name: Deploy preview
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
+      pull-requests: write
     environment:
       name: pr-preview-${{ github.event.number }}
       url: https://getbms.github.io/bms/pr-${{ github.event.number }}/

And for the cleanup job:

   cleanup:
     if: github.event.action == 'closed'
     name: Remove preview
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
 
     steps:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/deploy-preview.yml around lines 7 - 9, Remove the
workflow-level permissions block from the top of the workflow file and instead
add job-specific permissions. For the deploy job, add permissions with contents:
write and pull-requests: write, and for the cleanup job, add permissions with
only contents: write. This follows the principle of least privilege by ensuring
each job only receives the permissions it actually requires for its operations.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/deploy-prod.yml:
- Around line 32-35: The actions/checkout@v4 action is persisting Git
credentials by default, which unnecessarily exposes the GITHUB_TOKEN. Add a new
line to the with section of the actions/checkout@v4 action to set
persist-credentials: false, ensuring that Git credentials are not persisted to
.git/config since the deployment step provides an explicit token and no
subsequent steps require persisted credentials.
- Line 32: The actions/checkout@v4 action is using a floating tag which poses a
security risk. Replace the floating tag `@v4` with the full commit SHA of that
release to pin the action to an immutable version. Visit the actions/checkout
repository releases page on GitHub, find the commit SHA associated with the v4
tag, and update the action reference from actions/checkout@v4 to
actions/checkout@<full-commit-sha> using the exact SHA provided by GitHub.

In @.github/workflows/deploy-staging.yml:
- Line 53: The commit_message field currently uses ${{ github.sha }} which may
not match the actual deployed commit when the workflow is manually triggered
with a custom ref parameter. Instead, capture the actual HEAD SHA of the
checked-out repository (typically available as an output from the checkout step
or by running a git command to get the current HEAD SHA) and replace the ${{
github.sha }} reference in the commit_message with this captured actual SHA
value to ensure the staging commit metadata reflects the true deployed commit.
- Line 31: The GitHub Actions in the workflow file are pinned to mutable version
tags (actions/checkout@v4) which creates a supply chain security risk. Replace
all instances of mutable version tag references (including actions/checkout@v4
at line 31 and the similar references at lines 35 and 47) with their full commit
SHA hashes to make the action references immutable. Determine the correct commit
SHA for each action version and update the uses directive accordingly to
eliminate the vulnerability.
- Around line 31-33: The actions/checkout@v4 step is persisting credentials by
default, which makes the GITHUB_TOKEN available to all subsequent workflow steps
unnecessarily. Add persist-credentials: false to the with section of the
actions/checkout@v4 step to disable credential persistence. This hardens the
workflow by ensuring that the GitHub token is only available where explicitly
needed, specifically in the publish step that receives github_token directly.

---

Nitpick comments:
In @.github/workflows/deploy-preview.yml:
- Line 25: The `actions/checkout@v4` action currently persists the GitHub token
in `.git/config` by default, creating a security risk if malicious code executes
in subsequent workflow steps. Add the `persist-credentials: false` parameter to
the checkout action configuration to disable this behavior. Since the
`peaceiris/actions-gh-pages` action on line 41 provides its own `github_token`
parameter, this change will harden security without affecting the workflow's
functionality.
- Around line 7-9: Remove the workflow-level permissions block from the top of
the workflow file and instead add job-specific permissions. For the deploy job,
add permissions with contents: write and pull-requests: write, and for the
cleanup job, add permissions with only contents: write. This follows the
principle of least privilege by ensuring each job only receives the permissions
it actually requires for its operations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 209da4a6-e725-4eae-ab16-7d07f198ef58

📥 Commits

Reviewing files that changed from the base of the PR and between 0a3fbf5 and ebd0d28.

📒 Files selected for processing (3)
  • .github/workflows/deploy-preview.yml
  • .github/workflows/deploy-prod.yml
  • .github/workflows/deploy-staging.yml

Comment thread .github/workflows/deploy-prod.yml Outdated
Comment thread .github/workflows/deploy-prod.yml Outdated
Comment thread .github/workflows/deploy-staging.yml Outdated
Comment thread .github/workflows/deploy-staging.yml Outdated
Comment thread .github/workflows/deploy-staging.yml Outdated
Comment thread .github/workflows/deploy-preview.yml Fixed
Comment thread .github/workflows/deploy-preview.yml Fixed
Comment thread .github/workflows/deploy-prod.yml Fixed
Comment thread .github/workflows/deploy-prod.yml Fixed
Comment thread .github/workflows/deploy-staging.yml Fixed
Comment thread .github/workflows/deploy-staging.yml Fixed
- Pin all action references to immutable commit SHAs
- Add persist-credentials: false to all checkout steps
- Fix staging commit_message to use actual HEAD SHA after checkout
- Move deploy-preview permissions to job level (least privilege)
@hiranyasemindi hiranyasemindi merged commit 2c7b9ac into master Jun 17, 2026
10 checks passed
@hiranyasemindi hiranyasemindi deleted the feat/github-pages-deploy branch June 17, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants