Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-26.04
steps:
- uses: actions/checkout@v7
- uses: ruby/setup-ruby@v1
- uses: ruby/setup-ruby@v1.334.0
with:
# Match the Ruby bundled with openbolt, which runs the tasks in production
ruby-version: '3.2.11'
Expand Down
64 changes: 64 additions & 0 deletions data/sync/configs/20261024-setup-ruby-release-tag.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
# Reference ruby/setup-ruby by a release tag instead of `@v1`.
#
# In ruby/setup-ruby, `v1` is a branch, not a tag. Renovate can't resolve
# a branch to a commit, so `@v1` can be neither pinned to a digest nor held
# back by the shared preset's minimumReleaseAge. A release tag gives
# Renovate a version to pin, age and update; the shared ruby.json preset
# groups those updates with the Ruby patch updates.
#
# merge_github_workflows normally preserves each repo's `uses:` values, so
# `refresh_identities` makes the template's ruby/setup-ruby ref win for
# this session only. Every other Renovate-managed value is preserved as
# usual.
#
# Run this after simp/renovate-config#9 merges. Without it, every
# setup-ruby release opens its own immediate PR in every repo, instead of
# joining the grouped Ruby PR after a 2-day wait.
puppetsync::plan_config:
puppetsync:
permitted_project_types:
- pupmod
- pupmod_skeleton
plans:
sync:
github_api_delay_seconds: 1
merge_github_workflows:
files:
- pr_tests.yml
- tag_deploy.yml
preserve_blocks:
- jobs.acceptance
refresh_identities:
- ruby/setup-ruby
stages:
- install_gems
- checkout_git_feature_branch_in_each_repo
- merge_github_workflows
- git_commit_changes
- ensure_github_fork
- ensure_git_remote
- git_push_to_remote
- ensure_github_pr

approve_github_prs:
stages:
- approve_github_pr_for_each_repo

merge_github_prs:
stages:
- merge_github_pr_for_each_repo

git:
feature_branch: puppetsync/20261024-setup-ruby-release-tag
commit_message: |
[puppetsync] Reference ruby/setup-ruby by a release tag

`ruby/setup-ruby@v1` follows a branch, which Renovate can't pin or
hold back with a minimum release age. Reference the v1.334.0 release
tag instead, so Renovate pins it and proposes setup-ruby updates
together with the Ruby updates that need them.

github:
pr_user: silug # This should be the account that *submitted* the PRs
approval_message: ':+1: :ghost:'
10 changes: 7 additions & 3 deletions dist/puppetsync/plans/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,14 @@
default => Hash({ 'path' => "${wf_dir}/${f}", 'template' => file::read($template_path) }),
}
}.filter |$wf| { $wf =~ NotUndef }
# Optional: identities (e.g. 'ruby/setup-ruby') whose values come from
# the template this session, overriding the repo's preserved value.
# puppetsync.plans.sync.merge_github_workflows.refresh_identities
Hash({
'workflows' => $workflows,
'preserve_keys' => $opts.dig('merge_github_workflows', 'preserve_keys'),
'preserve_blocks' => $opts.dig('merge_github_workflows', 'preserve_blocks'),
'workflows' => $workflows,
'preserve_keys' => $opts.dig('merge_github_workflows', 'preserve_keys'),
'preserve_blocks' => $opts.dig('merge_github_workflows', 'preserve_blocks'),
'refresh_identities' => $opts.dig('merge_github_workflows', 'refresh_identities'),
})
}
}
Expand Down
4 changes: 4 additions & 0 deletions dist/puppetsync/tasks/merge_gha_workflows.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
"description": "YAML mapping keys whose scalar values are Renovate-managed and must be preserved from the existing file (default: uses, image, container, ruby-version, runs-on)",
"type": "Optional[Array[String[1]]]"
},
"refresh_identities": {
"description": "Identities whose values come from the template even when the repo has one (e.g. ['ruby/setup-ruby'] to move every ruby/setup-ruby ref to the template's): for a session that deliberately changes a preserved value without resetting the repo's other Renovate-managed values",
"type": "Optional[Array[String[1]]]"
},
"preserve_blocks": {
"description": "Dot-paths of mapping blocks the EXISTING file is authoritative for (e.g. ['jobs.acceptance']): its block replaces the template's, is appended when the template lacks it, and the template's block is removed when the existing file has none",
"type": "Optional[Array[String[1]]]"
Expand Down
32 changes: 27 additions & 5 deletions dist/puppetsync/tasks/merge_gha_workflows.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@
# other job's `needs:`, since GitHub rejects a workflow whose `needs:`
# names a job that doesn't exist (the template's aggregate check job
# needs every job, acceptance included).
#
# `refresh_identities` names identities (e.g. 'ruby/setup-ruby') whose values
# come from the template even when the repo already has one, including inside
# `preserve_blocks`: the way a session deliberately changes a preserved value,
# such as moving an action from a branch ref to a release tag, without
# touching the repo's other Renovate-managed values. An occurrence the
# template has no counterpart for (e.g. in a repo-owned block) takes the
# template's first value for that identity.

require 'fileutils'
require 'json'
Expand Down Expand Up @@ -184,7 +192,19 @@ def prune_needs(template, job_names)
end
end

def merge_workflow(template, existing_text, keys, blocks)
# The template's values for a refreshed identity at this [path, key,
# identity], or its first value for the identity anywhere when this context
# only exists in the repo (a preserved block the template lacks)
def template_refresh(template_values, id)
list = template_values.fetch(id, [])
return list unless list.empty?

template_values.select { |(_path, _key, ident), _values| ident == id[2] }.values.flatten.first(1)
end

def merge_workflow(template, existing_text, keys, blocks, refresh = [])
# Read before preserve_blocks splices repo content into the template
template_values = refresh.empty? ? {} : existing_values(template, keys)
template, preserved_blocks, removed_blocks = preserve_existing_blocks(template, existing_text, blocks)
removed_jobs = removed_blocks.filter_map { |path| path.delete_prefix('jobs.') if path.match?(/\Ajobs\.[^.]+\z/) }
template = prune_needs(template, removed_jobs)
Expand All @@ -197,12 +217,13 @@ def merge_workflow(template, existing_text, keys, blocks)
# differences (distinct versions per job, trailing comments) survive
# verbatim. Template entries with no counterpart in the existing file
# (a genuinely new or restored step) keep the template's value.
# Refreshed identities take the template's values instead.
counters = Hash.new(0)
preserved_scalars(Psych.parse(template), keys).each do |path, key, node|
next unless node.start_line == node.end_line

id = [path, key, identity(node.value)]
list = existing[id]
list = refresh.include?(id[2]) ? template_refresh(template_values, id) : existing[id]
value = list[counters[id]] || list.last
counters[id] += 1
next if value.nil?
Expand All @@ -217,7 +238,7 @@ def merge_workflow(template, existing_text, keys, blocks)
[lines.join("\n"), updated, preserved_blocks]
end

def merge_gha_workflows(workflows, keys, blocks)
def merge_gha_workflows(workflows, keys, blocks, refresh = [])
results = {}
workflows.each do |wf|
path = wf.fetch('path')
Expand All @@ -232,7 +253,7 @@ def merge_gha_workflows(workflows, keys, blocks)
end

existing_text = File.read(path)
merged, updated, preserved_blocks = merge_workflow(template, existing_text, keys, blocks)
merged, updated, preserved_blocks = merge_workflow(template, existing_text, keys, blocks, refresh)

if merged == existing_text
results[path] = { 'changed' => false }
Expand All @@ -252,5 +273,6 @@ def merge_gha_workflows(workflows, keys, blocks)
raise('No workflows given') unless workflows.is_a?(Array)
keys = params.fetch('preserve_keys', nil) || DEFAULT_PRESERVE_KEYS
blocks = params.fetch('preserve_blocks', nil) || []
refresh = params.fetch('refresh_identities', nil) || []

puts JSON.generate(merge_gha_workflows(workflows, keys, blocks))
puts JSON.generate(merge_gha_workflows(workflows, keys, blocks, refresh))
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ jobs:
echo "build_command=$GEM_BUILD_COMMAND" | tee -a "$GITHUB_OUTPUT"
echo "pkg_dir=$GEM_PKG_DIR" | tee -a "$GITHUB_OUTPUT"
echo "release_command=$GEM_RELEASE_COMMAND" | tee -a "$GITHUB_OUTPUT"
- uses: ruby/setup-ruby@v1
- uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: 2.7
bundler-cache: true
Expand Down Expand Up @@ -182,7 +182,7 @@ jobs:
with:
ref: ${{ github.ref }}
clean: true
- uses: ruby/setup-ruby@v1
- uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: 2.7
bundler-cache: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
echo "build_command=$GEM_BUILD_COMMAND" | tee -a "$GITHUB_OUTPUT"
echo "pkg_dir=$GEM_PKG_DIR" | tee -a "$GITHUB_OUTPUT"
echo "release_command=$GEM_RELEASE_COMMAND" | tee -a "$GITHUB_OUTPUT"
- uses: ruby/setup-ruby@v1
- uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: 2.7
bundler-cache: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ jobs:
echo "build_command=$GEM_BUILD_COMMAND" | tee -a "$GITHUB_OUTPUT"
echo "pkg_dir=$GEM_PKG_DIR" | tee -a "$GITHUB_OUTPUT"
echo "release_command=$GEM_RELEASE_COMMAND" | tee -a "$GITHUB_OUTPUT"
- uses: ruby/setup-ruby@v1
- uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: 2.7
bundler-cache: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1 # ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -35,7 +35,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -48,7 +48,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -62,7 +62,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -75,7 +75,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -88,7 +88,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand Down Expand Up @@ -141,7 +141,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby ${{matrix.puppet.ruby_version}}'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: ${{matrix.puppet.ruby_version}}
bundler-cache: true
Expand Down Expand Up @@ -193,7 +193,7 @@ jobs:
- name: checkout repo
uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
- name: bundle install
Expand Down
16 changes: 8 additions & 8 deletions modules/profile/files/pupmod/_github/workflows/pr_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1 # ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -35,7 +35,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -48,7 +48,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -62,7 +62,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -75,7 +75,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand All @@ -88,7 +88,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand Down Expand Up @@ -126,7 +126,7 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: 'Install Ruby ${{matrix.puppet.ruby_version}}'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: ${{matrix.puppet.ruby_version}}
bundler-cache: true
Expand Down Expand Up @@ -173,7 +173,7 @@ jobs:
- name: checkout repo
uses: actions/checkout@v7
- name: 'Install Ruby'
uses: ruby/setup-ruby@v1
uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
- name: bundle install
Expand Down
4 changes: 2 additions & 2 deletions modules/profile/files/pupmod/_github/workflows/tag_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
with:
ref: ${{ github.ref }}
clean: true
- uses: ruby/setup-ruby@v1
- uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand Down Expand Up @@ -174,7 +174,7 @@ jobs:
with:
ref: ${{ github.ref }}
clean: true
- uses: ruby/setup-ruby@v1
- uses: ruby/setup-ruby@v1.334.0
with:
ruby-version: '4.0.9'
bundler-cache: true
Expand Down
1 change: 1 addition & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended",
"github>simp/renovate-config",
"github>simp/renovate-config:ruby.json"
],
"github-actions": {
Expand Down
Loading
Loading