Skip to content

Add a Repository Setup workflow for the one-time repository settings - #170

Merged
Bill Traynor (wmat) merged 1 commit into
mainfrom
setup/repo-setup-workflow
Sep 30, 2026
Merged

Bill Traynor (wmat) merged 1 commit into
mainfrom
setup/repo-setup-workflow

Conversation

@wmat

Copy link
Copy Markdown
Collaborator

Three items on the Repository Setup Checklist are repository settings, not files:

  1. Pages source -> GitHub Actions
  2. the v* tag rule on the github-pages environment
  3. Dependabot alerts and security updates

None of them is visible to a pull request, so the checklist prose is the only thing enforcing them — and a skipped item does not fail loudly, it fails months later at an awkward moment. Both of the last two were added to the checklist reactively: the tag rule after a release deploy failed on riscv-performance-event-sampling (#165), and the Dependabot switch after a spec repository had accrued eleven open advisories with automated-security-fixes disabled and nothing opening a PR for any of them (#169).

This repository is itself missing the tag rule, which is a fair indication of how well prose enforces settings:

$ gh api repos/riscv/docs-spec-template/environments/github-pages/deployment-branch-policies
branch: main

What it does

.github/workflows/repo-setup.yml, workflow_dispatch only, with a checkbox per setting (all default on). It authenticates as GHTOKEN because GITHUB_TOKEN is refused for all three — creating a Pages site, changing environment settings and toggling Dependabot are admin-level operations the Actions app cannot perform.

Design choices worth reviewing:

  • Needs repo admin, which is more than the workflow scope template-sync.yml needs. When a call is refused, that step records FAIL with the manual instruction and the job carries on — applying two of three beats stopping at the first refusal — then exits non-zero at the end.
  • Reads before writing, so it skips anything already correct. Safe to re-run, and it doubles as an audit of these settings later.
  • Creates Pages already set to workflow rather than letting it default to Deploy from a branch, which is what queues the stray pages-build-deployment run that can overwrite the site afterwards.
  • Retries the environment read for ~15s, because enabling Pages creates github-pages but not always before the next step runs. If it still is not there, it says to re-run rather than reporting a failure.
  • Enables alerts before security updates, since the latter has nothing to act on without the former.
  • Handles the protected_branches case by reporting it instead of silently changing the environment's policy model.

Plumbing

Added to template-sync.yml's copy list and UPGRADING.md's template-owned list, so migrated repositories receive it — the gap #167 closed for template-sync.yml itself. README.adoc offers it as the fast path for checklist steps 3–5 while keeping the manual instructions as the fallback, and MIGRATION.md Step 16 points at it where a migrator is already standing in Actions.

Verification

I extracted the script and ran it against two real repositories with a gh shim that passes reads through and stubs writes:

REPO=riscv/riscv-high-assurance-cryptography
OK    Pages source is already 'workflow'
OK    a v* tag rule already exists
OK    Dependabot alerts already enabled
OK    Dependabot security updates already enabled

REPO=riscv/docs-spec-template
OK    Pages source is already 'workflow'
DONE  added the v* tag rule to github-pages     <- would add; write stubbed
OK    Dependabot alerts already enabled
OK    Dependabot security updates already enabled

Two different states, correct verdict on each — including correctly identifying this repository's missing rule.

That dry run also caught a real defect before it shipped: gh api prints its error body on stdout, so an unchecked current="$(gh api … 2>/dev/null)" captured a JSON blob as the value and drove the wrong branch — a 404 on /pages was reported as "Pages source changed from { "message": "Bad credentials" … }". All four reads now take their value only from a call whose exit status was checked. Worth knowing for any other workflow in this repository that reads through gh api.

The POST /pages creation path is the one branch no repository I have admin on could exercise, since all of them already have Pages; it is structurally the same as the PUT path next to it.

check-yaml and yamlfmt pass on both workflows.

🤖 Generated with Claude Code

Three items on the Repository Setup Checklist are repository settings rather than files: the Pages source, the v* tag rule on the github-pages environment, and Dependabot alerts and security updates. None of them is visible to a pull request, so the checklist is the only thing enforcing them, and a skipped item fails months later instead of loudly. The tag rule reached the checklist only after a release deploy failed on riscv-performance-event-sampling (#165); the Dependabot switch only after a spec repository had accrued eleven open advisories with nothing opening a PR for any of them. This repository is itself missing the tag rule.

repo-setup.yml applies all three from one dispatch, authenticating as GHTOKEN because GITHUB_TOKEN is refused for every one of them. It needs repo admin, which is more than template-sync.yml's workflow scope, so each step reports what to do by hand when a call is refused rather than aborting -- applying two of three beats stopping at the first refusal. Every step reads the current state first and skips when the setting is already correct, so it is safe to re-run and doubles as an audit.

Added to template-sync.yml's copy list and UPGRADING.md's template-owned list, so migrated repositories receive it. README.adoc offers it as the fast path while keeping the manual steps as the fallback, and MIGRATION.md Step 16 points at it where a migrator already is.

Verified by extracting the script and running it against riscv-high-assurance-cryptography and docs-spec-template with writes stubbed: the first reports all four settings already correct, the second correctly identifies the missing v* tag rule. That dry run also caught a real defect -- gh api prints its error body on stdout, so an unchecked read captured a JSON blob as the value and drove the wrong branch; all four reads now take their value only from a call whose exit status was checked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Bill Traynor <wmat@riscv.org>
@wmat
Bill Traynor (wmat) merged commit b3ee316 into main Sep 30, 2026
11 checks passed
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.

1 participant