Skip to content
Open
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
1 change: 1 addition & 0 deletions .github/workflows/build-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ permissions:
jobs:
build:
runs-on: ubuntu-latest
environment: production

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🟠 A required-reviewer gate here will stall the daily unattended rebuild — the highest-impact caveat of this PR.

This workflow is explicitly designed to run unattended on a schedule. From this file's own header:

The daily rebuild refreshes the @latest-pinned claude-code + failproofai npm globals.

schedule:
  - cron: '0 8 * * *' # daily at 08:00 UTC

Once the production environment has required reviewers — the stated intent of this PR — every trigger (this cron and push to main) creates a pending deployment that waits for a human. The nightly run will:

  • sit unapproved (nobody is watching at 08:00 UTC), then
  • be auto-cancelled after ~30 days, and
  • pile up as a rolling backlog of pending deployments.

Net effect: the automation this container exists for silently stops running.

Secondary issue — build-only validation is gated too. workflow_dispatch exposes push_to_ghcr: false ("validate the Dockerfile without publishing"). Because the gate sits at the job level, even a no-publish validation run now needs production approval, despite releasing nothing.

Options (pick per intent):

  1. Gate only actual manual pushes — make the environment conditional so scheduled/push runs skip it:
    environment: ${{ (github.event_name == 'workflow_dispatch' && inputs.push_to_ghcr) && 'production' || '' }}
    An empty environment name = no gate, so the nightly refresh stays unattended while manual publishes are gated. (Tradeoff: nightly pushes then bypass the gate — acceptable only if nightly @latest refreshes aren't what you want a human to approve.)
  2. Split build vs. push into two jobs and gate only the push job.
  3. Use a wait timer / branch policy rather than required reviewers for this workflow, so the cron proceeds after the timer instead of blocking indefinitely.

If the intent genuinely is "a human approves every image push, nightly included," this is working as designed — but that contradicts the header's "daily rebuild" purpose, so please confirm.

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
jobs:
publish:
runs-on: ubuntu-latest
environment: production

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🟡 Verify the production environment's deployment-branch policy allows tag refs — otherwise this blocks every release.

This job is triggered by release: published, so it runs on a tag ref (github.ref = refs/tags/<tag>), not a branch. GitHub Environments evaluate Deployment branches and tags against that ref. If you configure production with "Selected branches" — the intuitive way to "restrict production to main" — this publish job is rejected on every release (a tag is not a branch):

Tag <tag> is not allowed to deploy to production due to environment protection rules.

When configuring the environment:

  • Use "Selected branches and tags" and add a tag rule (e.g. v*), or
  • Leave "No restriction" on deployment branches and rely on required-reviewers instead.

Two more job-specific notes:

  • npm provenance identity changes. With environment: production set, the OIDC token's sub claim becomes repo:FailproofAI/failproofai:environment:production (instead of …:ref:refs/tags/…). Token auth via NODE_AUTH_TOKEN is unaffected, but the --provenance attestation (line 93) records this new builder identity. Harmless today; but if you ever adopt npm trusted publishing (OIDC), the environment name must be registered on the npm side.
  • Approval widens the race window on the final git push origin main. This job's last step (lines 102–117) commits the next-dev-version bump directly to main, and there is no concurrency: group. An approval gate delays execution, so two releases approved close together could race / double-bump main. Consider concurrency: { group: publish, cancel-in-progress: false } if you enable a wait timer or reviewers.

permissions:
contents: write
id-token: write
Expand Down