Add bootstrap mode for managed baseline files (#50 slice 1) - #70
Merged
Conversation
First slice of the Renovate-resilient template work: split file management into two modes so puppetsync stops clobbering values that Renovate maintains in place. - New profile::managed_file define wrapping the baseline file pattern with a mode parameter: 'enforce' (fully managed content, the previous behavior) or 'bootstrap' (lay down the complete file only when it doesn't exist, via replace => false) - All file-managing profiles (gemfile, git_files, puppet_lint, pdkignore, rspec, github_actions) now use the define and expose a Hiera-overridable mode parameter - Classification: the Gemfile defaults to 'bootstrap' (its gem pins are actively Renovate-managed); everything else stays 'enforce'. GHA workflows stay 'enforce' for now since puppetsync is still the delivery mechanism for workflow changes — they flip to bootstrap when the in-place merge stage lands (documented in the class) Verified end-to-end with the apply_puppet_role stage against a local pupmod fixture: a pre-seeded custom Gemfile survives the sync untouched while a drifted .gitignore is re-baselined and all missing baseline files (workflows, lint configs, spec_helper) are created; a fixture without a Gemfile gets the baseline one. Parser validation, plan show, the stage-list dry run, the CI e2e, and rspec all green. Refs simp#50 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 30, 2026
Member
|
LGTM — clean, well-scoped slice 1. Approving. Correctness (confirmed):
One consequence worth being explicit about (documented, not a blocker): with Gemfile now Suggestions:
|
- Rename managed_file's 'mode' parameter (and the per-profile passthroughs) to 'strategy': on a file-shaped define, 'mode' conventionally means POSIX permissions, and the rename is free now but breaking later once Hiera data references it - Add scripts/ci-managed-file-contract.sh, run by the CI bolt job: puppet-applies profile::managed_file both ways and asserts the load-bearing guarantee (bootstrap never overwrites an existing file; enforce and the default always do; both create missing files) so the Renovate-safety contract is CI-guarded instead of verified once manually Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
Thanks @nick-markowski — both suggestions taken in cbff800, and agreed on the consequence:
🤖 Generated with Claude Code |
nick-markowski
approved these changes
Jul 31, 2026
silug
added a commit
that referenced
this pull request
Jul 31, 2026
* Add merge_gha_workflows task and pipeline stage (#50 slice 3) Final slice of the Renovate-resilient template machinery: refresh GHA workflow files from their baseline templates while preserving every Renovate-managed value already in the repo. Approach: the template text is canonical — structure, comments, and formatting come from it byte-for-byte — and the Renovate-managed scalar values are grafted back on using Psych's node line/column coordinates. No YAML re-serialization happens at all, so comment/ format preservation holds by construction and no new gem (psych-pure) is needed. - preserve_keys (default: uses, image, container, ruby-version, runs-on; extensible per session config) selects which mapping keys' values are Renovate's - Values pair by [mapping path, key, identity], where identity is the part Renovate never changes (action before @, image before :, none for bare versions) — so distinct versions per job survive, trailing comments (pinned-digest conventions) ride along, and steps new to the template take the template's value - The merge_github_workflows stage merges only files that exist in BOTH the repo and the template chain (same per-module override resolution as profile::github_actions); creating/removing workflow files remains the profile's job, and repo-specific workflows with no template are never touched Verified with 13 specs (several driven by the real pr_tests.yml template, including byte-identity assertions) and an e2e run against a fixture with Renovate-bumped checkout@v7 / ruby-version 3.4.9 / ubuntu-24.04 plus structural drift: the merge restored template structure, preserved all bumped values (including per-job ones), left an untemplated custom workflow untouched, and a second run reported "1 unchanged". Real-world cases from pupmod-simp-pupmod dd98340 (ruby-version) and 837fb5e (runs-on) are covered by the defaults. After this and #70 merge, profile::github_actions can flip to bootstrap mode per project_type in Hiera, completing #50. Closes #50 * Address review feedback: debug output, ported registries, pair the flip - Remove the `warn stdin` debug line (it echoed every workflow template to stderr on each run) - identity() now handles ported registries (registry:5000/foo:8 pairs by everything before the tag colon), with a spec - Ship the profile::github_actions::strategy: bootstrap Hiera flip for pupmod/pupmod_skeleton WITH this stage: while the profile enforces, the apply stage overwrites workflows with pure template before this stage runs, so enabling merge_github_workflows pre-flip protects nothing. The key is inert until the managed_file strategy support merges, and the stage comment now documents the coupling. rubygem and unknown_with_ci project types stay enforce, since the merge stage does not cover them --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
First slice of #50 (Renovate-resilient templates): split baseline-file management into two modes so puppetsync stops clobbering values that Renovate maintains in place. Slices 2/3 (the in-place merge tasks for Gemfile and YAML) build on this.
Changes
profile::managed_filedefine — wraps the baselinefilepattern with amodeparameter:enforce(default): content fully managed; local changes overwritten — the previous behavior for every filebootstrap: lay down the complete file only when it doesn't exist (replace => false), for files whose values are maintained in place after creationgemfile,git_files,puppet_lint,pdkignore,rspec,github_actions), each exposing a Hiera-overridablemodeparameter — so classification lives in data when it needs to vary per project type.Gemfile→bootstrap(its pins are actively managed by Renovate viasimp/renovate-config:ruby; this is the file where clobbering hurts today)enforce, including GHA workflows: puppetsync is still the delivery mechanism for workflow changes (e.g. Add a REFERENCE.md freshness check to pr_tests.yml (bundle exec rake validate:strings) #46), so they stay fully managed until the YAML merge stage lands — at which point they flip via Hiera. The trade-off (an enforce sync can revert Renovate'suses:bumps until then) is documented on the class.No CHANGELOG.md update in this PR, per the new convention discussion (avoiding the every-PR conflict magnet).
Verification
End-to-end through the real
apply_puppet_rolestage against a localfile://pupmod fixture (temp config, not committed), withrole::pupmodclassified from Hiera viaproject_type:.gitignore.gitignorewas re-baselined; all missing baseline files were created (5 workflows,.pdkignore,.puppet-lint.rc,.rspec,spec/spec_helper.rb); the sync commit contained 11 files — not the GemfileAlso green:
puppet parser validateover all changed manifests,bolt plan show, thelist_pipeline_stagesdry run, the CI idempotency e2e, and rspec (154 examples, 0 failures).Refs #50
🤖 Generated with Claude Code