-
Notifications
You must be signed in to change notification settings - Fork 0
docs: add guide for keeping derived private repositories current #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 12 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
e1af344
docs: add guide for keeping derived private repositories current
Rafa-Ross b1f1dce
docs: address Codex review on updating guide
Rafa-Ross 2f7d76f
docs: use fetched template tag refs
Nickfost b1f0bc0
docs: make template updates collision-safe
Nickfost 832b531
docs: make template updates fail closed
Nickfost 188f62d
docs: address seventh Codex review on updating guide
Rafa-Ross 0cacdf6
docs+test: address eighth Codex review on updating guide
Rafa-Ross 2f5d4e1
docs: address ninth Codex review on updating guide
Rafa-Ross 2bc20e9
docs: address tenth Codex review on updating guide
Rafa-Ross 2a820f4
test: match policy assertion to temporary-ref tag verification
Rafa-Ross d093b1b
docs: abort before promoting a rewritten template tag
Rafa-Ross dceec93
docs+test: address twelfth Codex review on updating guide
Rafa-Ross 726bc0b
docs: persist trusted tag OIDs in versioned TEMPLATE_RELEASE data
Rafa-Ross 5653d9b
docs: address thirteenth Codex review on updating guide
Rafa-Ross c89bd7a
docs: peel annotated release tags to the tagged commit
Rafa-Ross 5178748
docs: compare raw tag-object OID, peel separately for the merge source
Rafa-Ross File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,189 @@ | ||
| # Keeping a private configuration repository up to date | ||
|
|
||
| A private configuration repository is created from this public template | ||
| and then lives its own life. This guide explains how it stays current. | ||
|
|
||
| ## Two different version numbers | ||
|
|
||
| - **`schema_version`** (inside `fleet.json`) is the version of the | ||
| *data contract* — the fields the engine and validator understand. It | ||
| changes rarely and only through an explicit migration (see below). | ||
| - **Template version** is the version of the *starting content* — the | ||
| scripts, validators, examples, and documentation you copied from this | ||
| template. It is tracked by the template's tagged releases, not by | ||
| anything inside `fleet.json`. | ||
|
|
||
| Bumping one never bumps the other. A new template release can ship | ||
| validator fixes with an unchanged `schema_version`; a schema migration | ||
| can happen without any other template change. | ||
|
|
||
| ## Template releases are versioned | ||
|
|
||
| This template publishes tagged releases. Record the release you started | ||
| from in your private repository (for example in its README), and review | ||
| release notes when updating. Treat template files as vendored code: | ||
| update them deliberately, not casually. | ||
|
|
||
| ## GitHub template repositories have no fork ancestry | ||
|
|
||
| A repository created with GitHub's "Use this template" button is **not** | ||
| a fork: it has no git ancestry link to the template, so | ||
| `git pull upstream` does not work and GitHub will never offer sync PRs. | ||
| Updating is an explicit operation: | ||
|
|
||
| 1. Start from a clean tree — no uncommitted or unstaged changes, | ||
| especially to `fleet.json`; the procedure restores `fleet.json` from | ||
| the recorded pre-merge commit and would silently discard an | ||
| uncommitted edit. Then add the template as a remote and fetch its | ||
| tags into that remote's tracking namespace. `--no-tags` prevents Git | ||
| from also creating adopter-visible tags. A retargeted upstream tag | ||
| updates a `refs/remotes/*` ref silently, so verify the reviewed | ||
| object ID yourself before using any previously fetched tag ref: | ||
|
|
||
| ```bash | ||
| git status --porcelain # must be empty | ||
|
Nickfost marked this conversation as resolved.
Outdated
|
||
| # one-time setup; on later runs verify the existing remote is really | ||
| # the template, not an unrelated remote that happens to share the name: | ||
| git remote add template https://github.com/RandomDevelopment/ci-fleet-config-template.git 2>/dev/null || true | ||
| git remote get-url template # must equal the URL above | ||
|
Nickfost marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Capture the tag as data and constrain its format. Never interpolate | ||
| # an unvalidated tag into shell commands: Git permits metacharacters | ||
| # in tag names, which would execute before the release is reviewed. | ||
| NEW_TAG=<new-tag> | ||
| [[ "$NEW_TAG" =~ ^[0-9A-Za-z][0-9A-Za-z._/-]{0,127}$ ]] || exit 1 | ||
|
|
||
| # Trusted tag OIDs live in refs/adopter/*, a namespace no remote | ||
| # refspec manages (a `git fetch --prune template` would delete refs | ||
| # under refs/remotes/template/* and silently reopen the rewrite | ||
|
Nickfost marked this conversation as resolved.
Outdated
|
||
| # window). Fetch into a temporary ref and promote only after | ||
| # comparison, so a retargeted upstream tag never becomes trusted. | ||
| PRIOR_TAG_OID="$(git rev-parse --verify -q "refs/adopter/template-tags/$NEW_TAG" || true)" | ||
| git update-ref -d refs/tmp/template-tag-check 2>/dev/null || true | ||
| if ! git fetch --no-tags template "refs/tags/$NEW_TAG:refs/tmp/template-tag-check"; then | ||
| echo "tag $NEW_TAG not found upstream" >&2; exit 1 | ||
| fi | ||
| NEW_TAG_OID="$(git rev-parse refs/tmp/template-tag-check)" | ||
| if [ -n "$PRIOR_TAG_OID" ] && [ "$NEW_TAG_OID" != "$PRIOR_TAG_OID" ]; then | ||
| # Fail closed: do not promote the rewritten tag; stop and review upstream. | ||
| git update-ref -d refs/tmp/template-tag-check | ||
| echo "template tag $NEW_TAG was rewritten upstream; refusing to use it" >&2 | ||
| exit 1 | ||
| fi | ||
| git update-ref "refs/adopter/template-tags/$NEW_TAG" "$NEW_TAG_OID" | ||
| git update-ref -d refs/tmp/template-tag-check | ||
| ``` | ||
|
|
||
| 2. Record the adopter commit, then merge the target template release | ||
| without committing. The explicit unrelated-history flag is required | ||
| on the first update and harmless after the first merge establishes | ||
| common ancestry: | ||
|
|
||
| ```bash | ||
| ADOPTER_HEAD="$(git rev-parse HEAD)" | ||
| git merge --no-ff --no-commit --allow-unrelated-histories \ | ||
| "refs/adopter/template-tags/$NEW_TAG" | ||
| ``` | ||
|
|
||
| If Git reports conflicts, leave the merge in progress and continue. | ||
| Whether or not it conflicted, restore the adopter-owned configuration | ||
| from the recorded pre-merge commit, then resolve and stage every other | ||
| conflict: | ||
|
|
||
|
Nickfost marked this conversation as resolved.
|
||
| ```bash | ||
| git restore --source="$ADOPTER_HEAD" --staged --worktree -- fleet.json | ||
| git status --short | ||
| ``` | ||
|
|
||
| If the release keeps the same `schema_version`, prove `fleet.json` | ||
| still has no staged change: | ||
|
|
||
| ```bash | ||
| git diff --cached --exit-code -- fleet.json | ||
| ``` | ||
|
|
||
| 3. Review the complete staged result — including any changes the merge | ||
| brings to `scripts/validate.sh`, the validator, or migration sources — | ||
| **before** executing anything the merge introduced. An erroneous or | ||
| compromised release must never run code in your environment | ||
| unreviewed: | ||
|
|
||
|
Nickfost marked this conversation as resolved.
|
||
| ```bash | ||
| git diff --cached | ||
| git status --short | ||
| ``` | ||
|
|
||
| If the release changes `schema_version`, run the now-reviewed target | ||
| release's migration tooling while this template merge is still | ||
| pending, then stage and review the mechanical `fleet.json` migration. | ||
| 4. Validate and commit: | ||
|
|
||
| ```bash | ||
| ./scripts/validate.sh --strict | ||
| git commit | ||
| ``` | ||
|
|
||
| Do not cherry-pick or format-patch a tag range: either can omit | ||
| intermediate or merge-result changes. | ||
|
|
||
| ## Validation is pinned to immutable releases | ||
|
|
||
| Controller `engine_ref` values and any reusable workflow references must | ||
| be full reviewed commit SHAs, not moving tags or branches. When you | ||
| update the pinned engine, resolve the exact merge commit on the engine's | ||
| default branch, review it, and pin that 40-hex SHA. | ||
|
|
||
| One limitation to understand: `./scripts/validate.sh --strict` runs the | ||
| validator **vendored in your repository**, so it verifies that | ||
| `engine_ref` is a well-formed 40-hex SHA but does not fetch that commit | ||
| or check it against the engine's actual contract. When you adopt a new | ||
| engine release whose `schema_version` is unchanged, update the vendored | ||
| schema/validator from the matching template release in the same change | ||
| (per the update procedure above) so validation actually exercises the | ||
| pinned contract. Releases that introduce a new `schema_version` are the | ||
| exception: import the new schema/validator in phase 2 of the two-phase | ||
| rollout below, after every deployed controller runs the new engine. | ||
|
|
||
| ## Dependabot update PRs | ||
|
|
||
| Keep a `.github/dependabot.yml` in the private repository covering | ||
| GitHub Actions. When your workflows pin actions or reusable workflows to | ||
| commit SHAs, Dependabot still opens update PRs for them (it understands | ||
| SHA-pinned actions with version comments). Review each PR like any | ||
| engine update: confirm the new SHA is a reviewed upstream release, then | ||
| let the strict validator and CI run before merge. | ||
|
|
||
| ## Schema migrations are explicit tooling | ||
|
|
||
| When the engine introduces a new `schema_version`, the migration is a | ||
| reviewed, mechanical transformation — not a hand edit. Apply it inside | ||
| the pending template merge above so the new schema, validator, migration, | ||
| and migrated private configuration are validated and committed together: | ||
|
|
||
| 1. Read the migration notes for the new schema version. | ||
| 2. Start the template merge, restore the adopter's pre-merge | ||
| `fleet.json`, and run the migration tooling shipped with that target | ||
| engine/template release before committing the merge. | ||
| 3. Run `./scripts/validate.sh --strict` and review the diff. | ||
|
Nickfost marked this conversation as resolved.
|
||
| 4. Roll out in two phases when controllers run the older engine. The | ||
| vendored validator understands one schema version, so importing the | ||
| new schema/validator and migrating `fleet.json` in the same change | ||
| would reject the configuration still needed by un-upgraded hosts: | ||
| - Phase 1 (old schema): merge a configuration commit that only | ||
| advances each controller's `engine_ref` to the new reviewed engine | ||
| commit, still expressed in the old `schema_version`, and let every | ||
| deployed controller upgrade. | ||
| - Phase 2 (new schema): once every still-deployed `active` or | ||
| `drained` controller runs the new engine, merge the template update | ||
| that imports the matching schema/validator and run the migration | ||
| above. | ||
| Retained `disabled` declarations have no running host and gate | ||
| neither phase. | ||
|
|
||
| ## Optional adopter registration, never telemetry | ||
|
|
||
| This project collects **no telemetry** and there is no phone-home of any | ||
| kind. If the community wants visibility into who operates a fleet, it is | ||
| strictly optional and opt-in: an `ADOPTERS.md` pull request or a | ||
| registration issue form on the public engine repository. Never a | ||
| requirement, never automatic. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.