Automate GitHub App and runner-group bootstrap - #75
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f59bdaae62
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 89d79ace17
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 831844a2aa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4fbb184683
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3ea10a39d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7255a7c323
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 73ab465534
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b7eebb4c4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb6b12c794
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Codex Review: Didn't find any major issues. 👍 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
113bad0 to
d946838
Compare
…acy rewrite The repo-wide 'RandomDevelopment' -> 'private-repository' scrub hit a shell numeric comparison inside scripts/bootstrap-github.sh, turning '$SECONDS -lt $deadline' into '$SECONDS -private-repository $deadline'. That is not valid bash: 'bash -n' fails and shellcheck reports SC1035/SC1072/SC1073, so the script cannot parse or run and exact-head CI 'Check shell scripts' fails. Restore the intended '-lt' operator and add a static regression test (scripts/test-bootstrap-syntax.sh) that fails deterministically on the corrupted operator (no network), independent of the flaky callback check. Other branch-vs-original diffs (MailThisForMe/TF2 -> 'downstream', the SECURITY.md contact placeholder) are intended privacy redactions already present in origin/main and are preserved.
…d config templates/config-repository/scripts/init.py hardcoded an RFC 5737 documentation address (198.51.100.0/24) as the default Docker default_address_pools base. PR #82's schema validation rejects RFC 5737 ranges under strict mode, so any config init.py generates now fails 'validate.py --strict'. The bootstrap test builds its fixture via init.py and the bootstrap strict-validates that pinned config, so the mocked bootstrap test could not bring up its routing callback. Emit 10.64.0.0/24, the operational CIDR the schema's own test (test_policy.py) uses as the valid example. The hand-written template fleet.json examples remain RFC 5737 placeholders because CI validates them non-strict (intended 'replace before use' examples).
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cfd251ca37
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| Path(sys.argv[1]).write_text(json.dumps({'name':sys.argv[2],'visibility':'selected','allows_public_repositories':False,'restricted_to_workflows':False,'selected_repository_ids':ids})) | ||
| PY | ||
| response=$temporary/group.json | ||
| write_auth_config "$installation_token" POST "https://api.github.com/orgs/$organization/actions/runner-groups" "$response" "$payload" |
There was a problem hiding this comment.
Track ambiguous runner-group creation for rollback
When GitHub commits this POST but curl times out or loses the response, or when the response JSON is truncated, execution exits before created_group=true, so the EXIT trap skips rollback even though the group now exists. Curl documents --max-time as a client-side transfer limit, so its expiry does not prove that GitHub rejected the request. Fresh evidence after the prior cancellation fix is that rollback ownership is still established only after the response is parsed; because repository name/ID pairs are verified afterward, a mistyped repository ID can remain authorized and corrected reruns treat the group as pre-existing. Mark creation as pending before the POST and reconcile the uncertain outcome before exiting.
AGENTS.md reference: AGENTS.md:L50-L57
Useful? React with 👍 / 👎.
| if [[ -e $bootstrap_recovery || -L $bootstrap_recovery ]]; then | ||
| [[ $mode != check ]] || die 'bootstrap credential recovery is pending; rerun live bootstrap first' | ||
| recover_conversion |
There was a problem hiding this comment.
Reject recovery records beside active credentials
When a stale recovery record coexists with an initialized host—for example after a partial backup restore—this unconditionally runs recover_conversion before inspecting the active bootstrap state. That function overwrites both the current PEM and bootstrap-app.env; if host.env is missing, it then removes the recovery record and continues with the recovered App, silently orphaning the previously active App identity, while a retained old host.env instead leaves the controller credentials inconsistent. Refuse this mixed state or prove that the recovery and active identities match before installing either file.
Useful? React with 👍 / 👎.
| "reserve_subnets": 1, | ||
| "default_address_pools": [ | ||
| {"base": "198.51.100.0/24", "size": 24 + (runner_networks + 1).bit_length()}, | ||
| {"base": "10.64.0.0/24", "size": 24 + (runner_networks + 1).bit_length()}, |
There was a problem hiding this comment.
Require an explicitly reviewed Docker address pool
Every initializer invocation now emits the operational-looking 10.64.0.0/24, which passes strict validation without any operator selecting or reviewing it. This contradicts the replacement workflow in templates/config-repository/README.md:50-60 and the initializer's own final prompt, and allows bootstrap preflight to accept an untouched pool even on sites where it overlaps existing host or VPN routing. Keep a rejected documentation placeholder for operator replacement, or require an explicit reviewed pool argument and update the initializer documentation and tests together.
AGENTS.md reference: templates/config-repository/AGENTS.md:L18-L18
Useful? React with 👍 / 👎.
| rm -f "$visible" | ||
|
|
||
| groups=$temporary/groups.json | ||
| write_auth_config "$installation_token" GET "https://api.github.com/orgs/$organization/actions/runner-groups?per_page=100" "$groups" |
There was a problem hiding this comment.
Paginate runner-group discovery
When the organization exposes more than 100 runner groups, this single-page request returns at most 100 while total_count describes all groups, so the parser exits before locating even a valid target group and every live or check invocation fails. GitHub's list runner groups endpoint documents the page and per_page pagination parameters. Fresh evidence after the selected-repository pagination fix is that group discovery still requests only one page; collect all bounded pages before matching the exact group name.
Useful? React with 👍 / 👎.
| staged=$temporary/host.env | ||
| printf '%s\n' "CI_FLEET_GITHUB_APP_CLIENT_ID=$CI_FLEET_GITHUB_APP_CLIENT_ID" "CI_FLEET_GITHUB_APP_INSTALLATION_ID=$installation_id" "CI_FLEET_GITHUB_APP_PRIVATE_KEY_FILE=/etc/ci-fleet/secrets/github-app.pem" 'CI_FLEET_RUNNER_TTL=6h' >"$staged" |
There was a problem hiding this comment.
Preserve the supported host-local runner TTL
When an operator uses a supported TTL other than 6h, or omits the optional value to use its default, this hardcoded staging file makes --check fail even though the GitHub identity and host configuration are valid; a live recovery rerun instead overwrites the operator's setting with 6h. The host contract in scripts/desired_state.py:31,128-138 explicitly accepts any valid duration of at least one hour, and docs/DESIRED-STATE.md:100 identifies the TTL as a host-local field. Preserve and validate the existing value, or expose it as an explicit bootstrap argument, rather than treating 6h as verified GitHub state.
Useful? React with 👍 / 👎.
Closes #27
Summary
Validation
scripts/test-bootstrap-github.shscripts/validate.shreachedINSTALLER_TESTS_OKandSTATUS_RECEIVER_INSTALL_TESTS_OK; final Docker smoke was omitted because this authorized repository-only environment has no Docker CLI/daemon (docker: command not found)External gate
Draft: an organization owner must create/install the App and approve the runner-group mutation in a prepared browser/API session. This run did not create an App, change runner groups, install credentials, or mutate live infrastructure.