mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 03:38:23 +00:00
feat(ci): mirror the source repository's main into a fork on every push
bf25eb2fc7removed the sync-main job because the fork had no token that may push .github/workflows/**: GITHUB_TOKEN cannot be granted the workflows permission, and the bot App is installed on infinito-nexus/core only. Since then a fork's main only moves when its owner syncs it by hand, and the fork's main has fallen 368 commits behind. The job is back with a token of its own: CI_SYNC_MAIN_TOKEN, a fine-grained personal access token limited to the fork, with Contents and Workflows write. main_from_repository.sh resolves the source through baseline_remote.sh, so the normalization and the off switch exist once: in infinito-nexus/core itself and with CI_SYNC_MAIN_SOURCE_REPOSITORY disabled the job ends green without reading the secret. Everywhere else a missing secret fails the job before any fetch or push and names the page that explains how to create it. The token reaches git as an HTTP header through GIT_CONFIG_* variables, never through argv or .git/config; checkout runs without persisted credentials so its own header does not compete. The job runs beside run-policy, not before it: CI keeps fetching its diff baseline from the source repository read-only, so a failed sync turns the run red without holding CI back. fix/ci-mirror-token tried the bot App instead (019fb572a7, 756b180f1d). That needs the App installed on every fork and granted Workflows write, which secrets.md rules out for the App, so the token here is a per-fork PAT. Checked: the script skips as infinito-nexus/core and with the sync disabled, and fails before fetching as a fork without the secret. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
34be0afdf7
commit
ffe77cdba9
5 files changed
+82
No files matched your search
@@ -12,6 +12,7 @@ This directory holds the shell helpers that GitHub Actions workflows under [`.gi
|
||||
| [resolve/](resolve/) | Derivation of structured workflow inputs and outputs from repository state. |
|
||||
| [update/](update/) | The scheduled `🔄 Update versions` pipeline (version bumps and PR open/refresh). |
|
||||
| [release/](release/) | Release-time gates that decide whether a tagged commit may be released. |
|
||||
| [sync/](sync/) | Mirroring the source repository's `main` into a fork on every push. |
|
||||
|
||||
A new helper MUST live in the subfolder that matches its responsibility. New responsibilities MAY motivate a new subfolder, but MUST NOT flatten back into the top level.
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# GitHub Sync Helpers 🔄
|
||||
|
||||
[main_from_repository.sh](main_from_repository.sh) force-pushes the source repository's `main` onto the current repository's `main`. The `🔄 Sync main` job of [entry-push-latest.yml](../../../.github/workflows/entry-push-latest.yml) runs it on every push.
|
||||
|
||||
The push needs the secret `CI_SYNC_MAIN_TOKEN`, see [secrets.md](../../../docs/contributing/tools/github/actions/secrets.md). The source repository and the switch to disable the sync are the repository variable `CI_SYNC_MAIN_SOURCE_REPOSITORY`, see [configuration.md](../../../docs/contributing/tools/github/actions/configuration.md).
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Env:
|
||||
# GITHUB_REPOSITORY - owner/repo of the running job, whose main is overwritten
|
||||
# CI_SYNC_MAIN_TOKEN - fine-grained token for GITHUB_REPOSITORY only, with Contents and Workflows write
|
||||
# CI_SYNC_MAIN_SOURCE_REPOSITORY, CI_SYNC_MAIN_SOURCE_REPOSITORY_IS_SET,
|
||||
# CI_SYNC_MAIN_SOURCE_REPOSITORY_DEFAULT - the source of main, see scripts/meta/resolve/baseline_remote.sh
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)"
|
||||
|
||||
: "${GITHUB_REPOSITORY:?Missing GITHUB_REPOSITORY}"
|
||||
|
||||
source_remote="$(bash "${REPO_ROOT}/scripts/meta/resolve/baseline_remote.sh")"
|
||||
if [[ "${source_remote}" == "origin" ]]; then
|
||||
echo "Main sync skipped: no source repository other than ${GITHUB_REPOSITORY} is configured."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -z "${CI_SYNC_MAIN_TOKEN:-}" ]]; then
|
||||
echo "ERROR: secret CI_SYNC_MAIN_TOKEN is not set, so ${GITHUB_REPOSITORY}:main cannot be synced from ${source_remote}." >&2
|
||||
echo "Create it as described in docs/contributing/tools/github/actions/secrets.md, or disable the sync through the repository variable CI_SYNC_MAIN_SOURCE_REPOSITORY." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Syncing ${GITHUB_REPOSITORY}:main from ${source_remote}."
|
||||
git fetch "${source_remote}" main:refs/remotes/main-sync-source/main --force
|
||||
|
||||
auth="$(printf 'x-access-token:%s' "${CI_SYNC_MAIN_TOKEN}" | base64 -w0)"
|
||||
GIT_CONFIG_COUNT=1 \
|
||||
GIT_CONFIG_KEY_0="http.https://github.com/.extraheader" \
|
||||
GIT_CONFIG_VALUE_0="AUTHORIZATION: basic ${auth}" \
|
||||
git push "https://github.com/${GITHUB_REPOSITORY}.git" refs/remotes/main-sync-source/main:refs/heads/main --force
|
||||
Reference in new issue
Block a user