From 688e04746cc55ba04a5a051c25cfb73cd907d710 Mon Sep 17 00:00:00 2001 From: Steven Pritchard Date: Fri, 24 Jul 2026 14:57:22 +0000 Subject: [PATCH 1/7] Surface the Forge API response in the deploy step curl --fail discards the response body, so a failed publish reports only an HTTP status (the simp-gpasswd 2.0.0 release died with a bare 403). Capture the body and status, print both, and fail on any non-2xx result so the Forge's own error message lands in the job log. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01XCnDsYaJDLiP8z8tafz9Tp --- .../pupmod/_github/workflows/tag_deploy.yml | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml index ecb731c..29f13d7 100644 --- a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml +++ b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml @@ -186,8 +186,22 @@ jobs: run: bundle exec pdk build --force - name: Deploy to Puppet Forge (skipped when prerelease) run: | - curl -X POST --silent --show-error --fail \ + file="$(find "$PWD/pkg" -name '*.tar.gz')" + echo "Uploading: ${file}" + response="$(mktemp)" + http_code="$(curl -X POST --silent --show-error \ --user-agent "$FORGE_USER_AGENT" \ --header "Authorization: Bearer ${PUPPETFORGE_API_TOKEN}" \ - --form "file=@$(find $PWD/pkg -name ''*.tar.gz'')" \ - "$FORGE_API_URL" + --form "file=@${file}" \ + --write-out '%{http_code}' \ + --output "$response" \ + "$FORGE_API_URL")" + echo "Forge API response (HTTP ${http_code}):" + cat "$response"; echo + case "$http_code" in + 2*) ;; + *) + echo "::error ::Puppet Forge upload failed with HTTP ${http_code} (see response above)" + exit 1 + ;; + esac From 973daeeff10e4d79d702e9fc05ed0ad1d8dead47 Mon Sep 17 00:00:00 2001 From: Steven Pritchard Date: Fri, 24 Jul 2026 15:12:42 +0000 Subject: [PATCH 2/7] Preserve the built module archive as a workflow artifact A failed Forge upload previously left nothing to download - the tarball existed only on the runner and the GitHub release carries no assets. Upload it before attempting the Forge POST so every tag run, pass or fail, leaves the exact archive available from the run page. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01XCnDsYaJDLiP8z8tafz9Tp --- .../profile/files/pupmod/_github/workflows/tag_deploy.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml index 29f13d7..034a3bf 100644 --- a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml +++ b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml @@ -184,6 +184,12 @@ jobs: bundler-cache: true - name: Build Puppet module (PDK) run: bundle exec pdk build --force + - name: Upload module archive as a workflow artifact + uses: actions/upload-artifact@v7 + with: + name: puppet-module + path: pkg/*.tar.gz + if-no-files-found: error - name: Deploy to Puppet Forge (skipped when prerelease) run: | file="$(find "$PWD/pkg" -name '*.tar.gz')" From a5b6def910f1ea14a86fd7549b74eed098e79808 Mon Sep 17 00:00:00 2001 From: Steven Pritchard Date: Fri, 24 Jul 2026 15:15:05 +0000 Subject: [PATCH 3/7] Attach the module archive to the GitHub release Release assets are permanent and publicly downloadable, unlike workflow artifacts (authenticated, expiring). Uploaded before the Forge POST so a failed publish still leaves the exact archive on the release. --clobber keeps job re-runs idempotent. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01XCnDsYaJDLiP8z8tafz9Tp --- modules/profile/files/pupmod/_github/workflows/tag_deploy.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml index 034a3bf..c935cea 100644 --- a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml +++ b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml @@ -190,6 +190,10 @@ jobs: name: puppet-module path: pkg/*.tar.gz if-no-files-found: error + - name: Attach module archive to the GitHub release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh release upload "${GITHUB_REF_NAME}" pkg/*.tar.gz --clobber - name: Deploy to Puppet Forge (skipped when prerelease) run: | file="$(find "$PWD/pkg" -name '*.tar.gz')" From 5eff094cdce3ae0b3e3f1d6944d129f0de2ec87d Mon Sep 17 00:00:00 2001 From: Steven Pritchard Date: Wed, 12 Aug 2026 19:49:19 +0000 Subject: [PATCH 4/7] Reconcile the tag_deploy.yml template with the deployed fleet The deployed workflows have moved on (PUPPET_VERSION '~> 8', Ruby 3.4.9, checkout@v7, github-script@v9, rake pupmod:build instead of pdk build) while the template still described the Puppet-7 era. Reconciling before the sync keeps the rollout diff down to the intended changes. Co-Authored-By: Claude Fable 5 --- .../pupmod/_github/workflows/tag_deploy.yml | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml index c935cea..b2c7a39 100644 --- a/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml +++ b/modules/profile/files/pupmod/_github/workflows/tag_deploy.yml @@ -39,7 +39,7 @@ on: - '[0-9]+\.[0-9]+\.[0-9]+\-[a-z]+[0-9]+' env: - PUPPET_VERSION: '~> 7' + PUPPET_VERSION: '~> 8' jobs: releng-checks: @@ -49,20 +49,20 @@ jobs: steps: - name: "Assert '${{ github.ref }}' is a tag" run: '[[ "$GITHUB_REF" =~ ^refs/tags/ ]] || { echo "::error ::GITHUB_REF is not a tag: ${GITHUB_REF}"; exit 1 ; }' - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 with: ref: ${{ github.ref }} clean: true - uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7 + ruby-version: 3.4.9 bundler-cache: true - run: bundle exec rake pkg:check_version - run: bundle exec rake pkg:compare_latest_tag - run: bundle exec rake pkg:create_tag_changelog - run: bundle exec rake metadata_lint - name: "Test that Puppet module can build" - run: "bundle exec pdk build --force" + run: "bundle exec rake pupmod:build" create-github-release: @@ -75,7 +75,7 @@ jobs: tag: ${{ steps.tag-check.outputs.tag }} steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: ref: ${{ github.ref }} clean: true @@ -132,21 +132,18 @@ jobs: runs-on: ubuntu-latest env: TARGET_REPO: ${{ github.repository }} - strategy: - matrix: - os: - - centos7 - - centos8 steps: - - name: Trigger RPM release workflow (${{ matrix.os }}) - uses: actions/github-script@v6 + # The build-OS matrix lives in release_rpms.yml (one dispatch builds + # every supported EL version) -- see simp/puppetsync#84 + - name: Trigger RPM release workflow + uses: actions/github-script@v9 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} TARGET_TAG: ${{ needs.create-github-release.outputs.tag }} with: github-token: ${{ secrets.SIMP_AUTO_GITHUB_TOKEN__REPO_SCOPE }} script: | - console.log( `== Building tag: '${ process.env.TARGET_TAG }' for os '${{ matrix.os}}'` ) + console.log( `== Building tag: '${ process.env.TARGET_TAG }'` ) const [owner, repo] = process.env.TARGET_REPO.split('/') await github.request('POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches', { owner: owner, @@ -156,11 +153,10 @@ jobs: inputs: { release_tag: process.env.TARGET_TAG, clean: 'no', - clobber: 'yes', - build_container_os: '${{ matrix.os }}' + clobber: 'yes' } }).then((result) => { - console.log( `== Submitted workflow dispatch to build RPMs from ${{ matrix.os }}: status ${result.status}` ) + console.log( `== Submitted workflow dispatch to build RPMs: status ${result.status}` ) }) deploy-to-puppet-forge: @@ -174,16 +170,16 @@ jobs: FORGE_API_URL: https://forgeapi.puppet.com/v3/releases steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: ref: ${{ github.ref }} clean: true - uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7 + ruby-version: 3.4.9 bundler-cache: true - - name: Build Puppet module (PDK) - run: bundle exec pdk build --force + - name: Build Puppet module + run: bundle exec rake pupmod:build - name: Upload module archive as a workflow artifact uses: actions/upload-artifact@v7 with: From cfa9212158d72daabf477aad64dd266a146b9fd5 Mon Sep 17 00:00:00 2001 From: Steven Pritchard Date: Wed, 12 Aug 2026 19:49:19 +0000 Subject: [PATCH 5/7] Move the RPM build-OS matrix into release_rpms.yml (#84) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every tag push has been dispatching two release_rpms.yml runs hardcoded to the retired centos7/centos8 containers, overriding #80's el8 default — all tag-triggered RPM builds fail. The caller templates now dispatch once with no OS override, and release_rpms.yml owns the build-OS list via a build_container_oses input (default '["el8","el9","el10"]', narrowable on manual runs). Per-release work (release lookup/creation, the clean-input asset wipe) is split into a resolve-release job so the parallel per-OS legs cannot race on release autocreation or wipe each other's uploads, and both build inputs are required: false so omitting them in dispatch calls is well-defined. Also fixes validate-inputs writing '{name}={value}' to GITHUB_OUTPUT — invalid syntax, so prebuild_suffix/build_semver never populated and prerelease tags were treated as full releases. Co-Authored-By: Claude Fable 5 --- .../files/_github/workflows/release_rpms.yml | 104 ++++++++++-------- .../workflows/tag_deploy_github-rpms.yml | 16 +-- .../tag_deploy_rubygem__github-rpms.yml | 16 +-- 3 files changed, 73 insertions(+), 63 deletions(-) diff --git a/modules/profile/files/_github/workflows/release_rpms.yml b/modules/profile/files/_github/workflows/release_rpms.yml index fb68587..26d39bf 100644 --- a/modules/profile/files/_github/workflows/release_rpms.yml +++ b/modules/profile/files/_github/workflows/release_rpms.yml @@ -51,13 +51,13 @@ on: description: "Create release if missing? (tag must exist)" required: false default: 'yes' - build_container_os: - description: "Build container OS" - required: true - default: 'el8' + build_container_oses: + description: "Build container OSes (JSON list)" + required: false + default: '["el8","el9","el10"]' build_container_tag: description: "Build container tag" - required: true + required: false default: 'latest' target_repo: description: "Target repo (instead of this one)" @@ -90,13 +90,20 @@ env: RELEASE_TAG: ${{ github.event.inputs.release_tag }} jobs: - create-and-attach-rpms-to-github-release: + # Per-release work (resolve or create the release, optionally wipe its + # assets) runs ONCE; the per-OS builds fan out from it below. + # See simp/puppetsync#84 + resolve-release: name: > - Build and attach RPMs to Release: + Resolve GitHub Release: ${{ (github.event.inputs.target_repo != null && format('{0}/{1}', github.repository_owner, github.event.inputs.target_repo)) || github.repository }} ${{ github.event.inputs.release_tag }} - (build os: ${{ github.event.inputs.build_container_os }}) - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 + outputs: + release_id: ${{ steps.release-api.outputs.id }} + build_semver: ${{ steps.validate-inputs.outputs.build_semver }} + prebuild_suffix: ${{ steps.validate-inputs.outputs.prebuild_suffix }} + prebuild_number: ${{ steps.validate-inputs.outputs.prebuild_number }} steps: - name: "Validate inputs" id: validate-inputs @@ -108,13 +115,13 @@ jobs: if [[ "$RELEASE_TAG" =~ ^(simp-|v)?([0-9]+\.[0-9]+\.[0-9]+)(-(rc|RC|[Aa]lpha|[Bb]eta|pre|post)?([0-9]+)?)?$ ]]; then if [ -n "${BASH_REMATCH[5]}" ]; then - echo "{prebuild_number}={${BASH_REMATCH[5]#-}}" >> $GITHUB_OUTPUT + echo "prebuild_number=${BASH_REMATCH[5]#-}" >> $GITHUB_OUTPUT fi if [ -n "${BASH_REMATCH[3]}" ]; then - echo "{prebuild_suffix}={${BASH_REMATCH[3]#-}}" >> $GITHUB_OUTPUT + echo "prebuild_suffix=${BASH_REMATCH[3]#-}" >> $GITHUB_OUTPUT fi if [ -n "${BASH_REMATCH[2]}" ]; then - echo "{build_semver}={${BASH_REMATCH[2]}}" >> $GITHUB_OUTPUT + echo "build_semver=${BASH_REMATCH[2]}" >> $GITHUB_OUTPUT fi else printf '::error ::Release Tag format is not SemVer, X.Y.Z-R, X.Y.Z-: "%s"\n' "$RELEASE_TAG" @@ -124,13 +131,12 @@ jobs: - name: > Query info for ${{ env.TARGET_REPO }} release ${{ github.event.inputs.release_tag }} ${{ steps.validate-inputs.outputs.prebuild_suffix }} - build os ${{ github.event.inputs.build_container_os }} (autocreate_release = '${{ github.event.inputs.autocreate_release }}') id: release-api env: AUTOCREATE_RELEASE: ${{ github.event.inputs.autocreate_release }} PREBUILD_TAG: ${{ steps.validate-inputs.outputs.prebuild_suffix }} - uses: actions/github-script@v6 + uses: actions/github-script@v9 with: github-token: ${{ github.event.inputs.target_repo_token || secrets.GITHUB_TOKEN }} script: | @@ -197,8 +203,39 @@ jobs: err => { throw err } ) + - name: "Wipe all previous assets from GitHub Release (when clean == 'yes')" + if: ${{ github.event.inputs.clean == 'yes' && github.event.inputs.dry_run != 'yes' }} + uses: actions/github-script@v9 + env: + release_id: ${{ steps.release-api.outputs.id }} + with: + github-token: ${{ github.event.inputs.target_repo_token || secrets.GITHUB_TOKEN }} + script: | + const release_id = process.env.release_id + const [owner, repo] = process.env.TARGET_REPO.split('/') + const existingAssets = await github.rest.repos.listReleaseAssets({ owner, repo, release_id }) + + console.log( ` !! !! Wiping ALL uploaded assets for ${owner}/${repo} release (id: ${release_id})`) + existingAssets.data.forEach(async function(asset){ + asset_id = asset.id + console.log( ` !! !! !! Wiping existing asset for ${asset.name} (id: ${asset_id})`) + await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id }) + }) + + create-and-attach-rpms-to-github-release: + name: > + Build and attach RPMs to Release: + ${{ (github.event.inputs.target_repo != null && format('{0}/{1}', github.repository_owner, github.event.inputs.target_repo)) || github.repository }} + ${{ github.event.inputs.release_tag }} + (build os: ${{ matrix.os }}) + needs: [ resolve-release ] + runs-on: ubuntu-24.04 + strategy: + matrix: + os: ${{ fromJSON(github.event.inputs.build_container_oses) }} + steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: repository: ${{ env.TARGET_REPO }} ref: ${{ env.RELEASE_TAG }} @@ -206,11 +243,11 @@ jobs: fetch-depth: 0 - name: 'Customize RPM Release tag via build/rpm_metadata/release (pre-release only)' - if: steps.validate-inputs.outputs.prebuild_suffix + if: needs.resolve-release.outputs.prebuild_suffix env: - BUILD_SEMVER: ${{ steps.validate-inputs.outputs.build_semver }} - PREBUILD_TAG: ${{ steps.validate-inputs.outputs.prebuild_suffix }} - PREBUILD_NUMBER: ${{ steps.validate-inputs.outputs.prebuild_number }} + BUILD_SEMVER: ${{ needs.resolve-release.outputs.build_semver }} + PREBUILD_TAG: ${{ needs.resolve-release.outputs.prebuild_suffix }} + PREBUILD_NUMBER: ${{ needs.resolve-release.outputs.prebuild_number }} # Note: To accomodate the capabilities of EL7's version of RPM, the # release number is formatted according to the Fedora Packaging # Guidelines' "Traditional versioning" conventions: @@ -233,7 +270,7 @@ jobs: - name: 'Customize RPM Release tag via build/rpm_metadata/release (RPM rebuild)' if: ${{ github.event.inputs.rebuild_number != '' }} env: - BUILD_SEMVER: ${{ steps.validate-inputs.outputs.build_semver }} + BUILD_SEMVER: ${{ needs.resolve-release.outputs.build_semver }} REBUILD_NUMBER: ${{ github.event.inputs.rebuild_number }} run: | mkdir -p build/rpm_metadata @@ -249,7 +286,7 @@ jobs: - name: > Build & Sign RPMs for ${{ github.event.inputs.release_tag }} - Release (${{ github.event.inputs.build_container_os }}) + Release (${{ matrix.os }}) uses: simp/github-action-build-and-sign-pkg-single-rpm@v2 id: build-and-sign-rpm with: @@ -257,36 +294,17 @@ jobs: gpg_signing_key_id: ${{ secrets.SIMP_DEV_GPG_SIGNING_KEY_ID }} gpg_signing_key_passphrase: ${{ secrets.SIMP_DEV_GPG_SIGNING_KEY_PASSPHRASE }} simp_core_ref_for_building_rpms: ${{ secrets.SIMP_CORE_REF_FOR_BUILDING_RPMS }} - simp_builder_docker_image: 'ghcr.io/simp/simp-${{ github.event.inputs.build_container_os }}-build:${{ github.event.inputs.build_container_tag }}' + simp_builder_docker_image: 'ghcr.io/simp/simp-${{ matrix.os }}-build:${{ github.event.inputs.build_container_tag }}' path_to_build: "${{ (github.event.inputs.path_to_build != null && format('{0}/{1}', github.workspace, github.event.inputs.path_to_build)) || github.workspace }}" verbose: 'no' #${{ github.event.inputs.verbose }} - - name: "Wipe all previous assets from GitHub Release (when clean == 'yes')" - if: ${{ github.event.inputs.clean == 'yes' && github.event.inputs.dry_run != 'yes' }} - uses: actions/github-script@v6 - env: - release_id: ${{ steps.release-api.outputs.id }} - with: - github-token: ${{ github.event.inputs.target_repo_token || secrets.GITHUB_TOKEN }} - script: | - const release_id = process.env.release_id - const [owner, repo] = process.env.TARGET_REPO.split('/') - const existingAssets = await github.rest.repos.listReleaseAssets({ owner, repo, release_id }) - - console.log( ` !! !! Wiping ALL uploaded assets for ${owner}/${repo} release (id: ${release_id})`) - existingAssets.data.forEach(async function(asset){ - asset_id = asset.id - console.log( ` !! !! !! Wiping existing asset for ${asset.name} (id: ${asset_id})`) - await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id }) - }) - - name: "Upload RPM file(s) to GitHub Release (dry_run != 'yes')" if: ${{ github.event.inputs.dry_run != 'yes' }} - uses: actions/github-script@v6 + uses: actions/github-script@v9 env: rpm_file_paths: ${{ steps.build-and-sign-rpm.outputs.rpm_file_paths }} rpm_gpg_file: ${{ steps.build-and-sign-rpm.outputs.rpm_gpg_file }} - release_id: ${{ steps.release-api.outputs.id }} + release_id: ${{ needs.resolve-release.outputs.release_id }} clobber: ${{ github.event.inputs.clobber }} clean: ${{ github.event.inputs.clean }} dry_run: ${{ github.event.inputs.dry_run }} diff --git a/modules/profile/files/_github/workflows/tag_deploy_github-rpms.yml b/modules/profile/files/_github/workflows/tag_deploy_github-rpms.yml index dc3461b..ec1c090 100644 --- a/modules/profile/files/_github/workflows/tag_deploy_github-rpms.yml +++ b/modules/profile/files/_github/workflows/tag_deploy_github-rpms.yml @@ -106,13 +106,10 @@ jobs: runs-on: ubuntu-latest env: TARGET_REPO: ${{ github.repository }} - strategy: - matrix: - os: - - centos7 - - centos8 steps: - - name: Trigger RPM release workflow (${{ matrix.os }}) + # The build-OS matrix lives in release_rpms.yml (one dispatch builds + # every supported EL version) -- see simp/puppetsync#84 + - name: Trigger RPM release workflow uses: actions/github-script@v6 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} @@ -120,7 +117,7 @@ jobs: with: github-token: ${{ secrets.SIMP_AUTO_GITHUB_TOKEN__REPO_SCOPE }} script: | - console.log( `== Building tag: '${ process.env.TARGET_TAG }' for os '${{ matrix.os}}'` ) + console.log( `== Building tag: '${ process.env.TARGET_TAG }'` ) const [owner, repo] = process.env.TARGET_REPO.split('/') await github.request('POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches', { owner: owner, @@ -130,9 +127,8 @@ jobs: inputs: { release_tag: process.env.TARGET_TAG, clean: 'no', - clobber: 'yes', - build_container_os: '${{ matrix.os }}' + clobber: 'yes' } }).then((result) => { - console.log( `== Submitted workflow dispatch to build RPMs from ${{ matrix.os }}: status ${result.status}` ) + console.log( `== Submitted workflow dispatch to build RPMs: status ${result.status}` ) }) diff --git a/modules/profile/files/_github/workflows/tag_deploy_rubygem__github-rpms.yml b/modules/profile/files/_github/workflows/tag_deploy_rubygem__github-rpms.yml index 1e31ed6..6d3a6d9 100644 --- a/modules/profile/files/_github/workflows/tag_deploy_rubygem__github-rpms.yml +++ b/modules/profile/files/_github/workflows/tag_deploy_rubygem__github-rpms.yml @@ -173,13 +173,10 @@ jobs: runs-on: ubuntu-latest env: TARGET_REPO: ${{ github.repository }} - strategy: - matrix: - os: - - centos7 - - centos8 steps: - - name: Trigger RPM release workflow (${{ matrix.os }}) + # The build-OS matrix lives in release_rpms.yml (one dispatch builds + # every supported EL version) -- see simp/puppetsync#84 + - name: Trigger RPM release workflow uses: actions/github-script@v6 env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} @@ -187,7 +184,7 @@ jobs: with: github-token: ${{ secrets.SIMP_AUTO_GITHUB_TOKEN__REPO_SCOPE }} script: | - console.log( `== Building tag: '${ process.env.TARGET_TAG }' for os '${{ matrix.os}}'` ) + console.log( `== Building tag: '${ process.env.TARGET_TAG }'` ) const [owner, repo] = process.env.TARGET_REPO.split('/') await github.request('POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches', { owner: owner, @@ -197,9 +194,8 @@ jobs: inputs: { release_tag: process.env.TARGET_TAG, clean: 'no', - clobber: 'yes', - build_container_os: '${{ matrix.os }}' + clobber: 'yes' } }).then((result) => { - console.log( `== Submitted workflow dispatch to build RPMs from ${{ matrix.os }}: status ${result.status}` ) + console.log( `== Submitted workflow dispatch to build RPMs: status ${result.status}` ) }) From 7b2d394542ba3931df9f37a15cf5f51cdcdf5acf Mon Sep 17 00:00:00 2001 From: Steven Pritchard Date: Wed, 12 Aug 2026 19:49:19 +0000 Subject: [PATCH 6/7] Retire the EL7/EL8 tag_deploy variant (#84) EL7 is gone fleet-wide and the per-OS choice now lives in release_rpms.yml, so tag_deploy_github-rpms-el7-el8.yml had no remaining purpose. pkg-r10k and simp-adapter fall back to the standard simp_unknown presets, whose absent list already removes the file. Co-Authored-By: Claude Fable 5 --- data/project_types/simp_unknown.yaml | 14 -- data/repos/pkg-r10k.yaml | 3 - data/repos/simp-adapter.yaml | 4 - .../tag_deploy_github-rpms-el7-el8.yml | 135 ------------------ 4 files changed, 156 deletions(-) delete mode 100644 data/repos/pkg-r10k.yaml delete mode 100644 data/repos/simp-adapter.yaml delete mode 100644 modules/profile/files/_github/workflows/tag_deploy_github-rpms-el7-el8.yml diff --git a/data/project_types/simp_unknown.yaml b/data/project_types/simp_unknown.yaml index 5defec0..ecb44f9 100644 --- a/data/project_types/simp_unknown.yaml +++ b/data/project_types/simp_unknown.yaml @@ -19,20 +19,6 @@ profile::github_actions::absent_action_files__rpms: - tag_deploy_github-rpms-el7-el8.yml - validate_tokens.yml -profile::github_actions::present_action_files__rpms_el7_el8: - - tag_deploy_github-rpms-el7-el8.yml - - release_rpms.yml - - validate_tokens_asset.yml - - add_new_issue_to_triage_project.yml - -profile::github_actions::absent_action_files__rpms_el7_el8: - - pr_glci.yml # PR-triggered GLCI actions - - pr_glci_manual.yml # --> manual trigger for external contributors - - pr_glci_cleanup.yml # --> clean up old GLCI branches - - tag_deploy_github-only.yml - - tag_deploy_github-rpms.yml - - validate_tokens.yml - profile::github_actions::present_action_files__github_only: - tag_deploy_github-only.yml # Release on tag - validate_tokens_asset.yml diff --git a/data/repos/pkg-r10k.yaml b/data/repos/pkg-r10k.yaml deleted file mode 100644 index ea694fc..0000000 --- a/data/repos/pkg-r10k.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -profile::github_actions::present_action_files: "%{alias('profile::github_actions::present_action_files__rpms_el7_el8')}" -profile::github_actions::absent_action_files: "%{alias('profile::github_actions::absent_action_files__rpms_el7_el8')}" diff --git a/data/repos/simp-adapter.yaml b/data/repos/simp-adapter.yaml deleted file mode 100644 index 8f8862f..0000000 --- a/data/repos/simp-adapter.yaml +++ /dev/null @@ -1,4 +0,0 @@ ---- -profile::github_actions::present_action_files: "%{alias('profile::github_actions::present_action_files__rpms_el7_el8')}" -profile::github_actions::absent_action_files: "%{alias('profile::github_actions::absent_action_files__rpms_el7_el8')}" - diff --git a/modules/profile/files/_github/workflows/tag_deploy_github-rpms-el7-el8.yml b/modules/profile/files/_github/workflows/tag_deploy_github-rpms-el7-el8.yml deleted file mode 100644 index f2432f2..0000000 --- a/modules/profile/files/_github/workflows/tag_deploy_github-rpms-el7-el8.yml +++ /dev/null @@ -1,135 +0,0 @@ -# Deploy GitHub release when a SemVer tag is pushed, trigger el7 + el8 RPM build -# ------------------------------------------------------------------------------ -# -# NOTICE: **This file is maintained with puppetsync** -# -# This file is updated automatically as part of a standardized asset baseline. -# -# The next baseline sync will overwrite any local changes to this file! -# -# ============================================================================== -# -# This pipeline uses the following GitHub Action Secrets: -# -# GitHub Secret variable Notes -# ------------------------------- --------------------------------------- -# SIMP_CORE_REF_FOR_BUILDING_RPMS simp-core ref (tag) to use to build -# RPMs with `rake pkg:single` -# SIMP_DEV_GPG_SIGNING_KEY GPG signing key's secret key -# SIMP_DEV_GPG_SIGNING_KEY_ID User ID (name) of signing key -# SIMP_DEV_GPG_SIGNING_KEY_PASSPHRASE Passphrase to use GPG signing key -# -# ------------------------------------------------------------------------------ -# -# NOTES: -# -# * The CHANGELOG text is altered to remove RPM-style date headers, which don't -# render well as markdown on the GitHub release pages -# ---- -name: 'Tag: Release to GitHub' - -on: - push: - tags: - # NOTE: These filter patterns aren't actually regexes: - # https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet - - '[0-9]+\.[0-9]+\.[0-9]+' - - '[0-9]+\.[0-9]+\.[0-9]+\-[a-z]+[0-9]+' - -jobs: - create-github-release: - name: Deploy GitHub Release - if: github.repository_owner == 'simp' - runs-on: ubuntu-latest - outputs: - prerelease: ${{ steps.tag-check.outputs.prerelease }} - tag: ${{ steps.tag-check.outputs.tag }} - steps: - - name: Checkout code - uses: actions/checkout@v5 - with: - ref: ${{ github.ref }} - clean: true - fetch-depth: 0 - - - name: Get tag & annotation info (${{github.ref}}) - id: tag-check - run: | - tag="${GITHUB_REF/refs\/tags\//}" - annotation="$(git for-each-ref "$GITHUB_REF" --format='%(contents)' --count=1)" - annotation_title="$(echo "$annotation" | head -1)" - - if [[ "$tag" =~ ^(simp-|v)?[0-9]+\.[0-9]+\.[0-9]+(-(rc|alpha|beta|pre|post)?([0-9]+)?)?$ ]]; then - if [ -n "${BASH_REMATCH[2]}" ]; then - prerelease=yes - annotation_title="Pre-release of ${tag}" - fi - else - printf '::error ::Release Tag format is not SemVer, X.Y.Z-R, X.Y.Z-: "%s"\n' "$RELEASE_TAG" - exit 88 - fi - - echo "tag=$tag" | tee -a "$GITHUB_OUTPUT" - echo "prerelease=$prerelease" | tee -a "$GITHUB_OUTPUT" - echo "TARGET_TAG=$tag" | tee -a "$GITHUB_ENV" - - # Prepare annotation body as a file for the next step - # - # * The GitHub Release renders the text in this file as markdown - # * The `perl -pe` removes RPM-style date headers from the CHANGELOG, - # because they don't render well as markdown on the Release page - echo "RELEASE_MESSAGE<> "$GITHUB_ENV" - printf '%s\n\n' "$annotation_title" >> "$GITHUB_ENV" - echo "$annotation" | tail -n +2 | \ - perl -pe 'BEGIN{undef $/;} s/\n\* (Mon|Tue|Wed|Thu|Fri|Sat|Sun) .*?\n//smg;' >> "$GITHUB_ENV" - echo "EOF$$" >> "$GITHUB_ENV" - - - name: Create Release - id: create_release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - echo "${RELEASE_MESSAGE}" > /tmp/.commit-msg.txt - args=(-F /tmp/.commit-msg.txt) - [[ ${{ steps.tag-check.outputs.prerelease }} == yes ]] && args+=(--prerelease) - - gh release create ${args[@]} "$TARGET_TAG" - - build-and-attach-rpms: - name: Trigger RPM release - needs: [ create-github-release ] - if: github.repository_owner == 'simp' - runs-on: ubuntu-latest - env: - TARGET_REPO: ${{ github.repository }} - strategy: - matrix: - os: - - centos7 - - centos8 - steps: - - name: Trigger RPM release workflow (${{ matrix.os }}) - uses: actions/github-script@v6 - env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - TARGET_TAG: ${{ needs.create-github-release.outputs.tag }} - with: - github-token: ${{ secrets.SIMP_AUTO_GITHUB_TOKEN__REPO_SCOPE }} - script: | - console.log( `== Building tag: '${ process.env.TARGET_TAG }' for os '${{ matrix.os}}'` ) - const [owner, repo] = process.env.TARGET_REPO.split('/') - await github.request('POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches', { - owner: owner, - repo: repo, - workflow_id: 'release_rpms.yml', - ref: process.env.DEFAULT_BRANCH, - inputs: { - release_tag: process.env.TARGET_TAG, - clean: 'no', - clobber: 'yes', - build_container_os: '${{ matrix.os }}' - } - }).then((result) => { - console.log( `== Submitted workflow dispatch to build RPMs from ${{ matrix.os }}: status ${result.status}` ) - }) From 346cdc308ca20eb9044eeebaa3e69b4c5070fdb5 Mon Sep 17 00:00:00 2001 From: Steven Pritchard Date: Wed, 12 Aug 2026 19:49:19 +0000 Subject: [PATCH 7/7] Add session config: fleet rollout of the tag_deploy/release_rpms rework Co-Authored-By: Claude Fable 5 --- .../20260812-tag-deploy-rpm-matrix.yaml | 73 +++++++++++++++++++ data/sync/configs/latest.yaml | 2 +- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 data/sync/configs/20260812-tag-deploy-rpm-matrix.yaml diff --git a/data/sync/configs/20260812-tag-deploy-rpm-matrix.yaml b/data/sync/configs/20260812-tag-deploy-rpm-matrix.yaml new file mode 100644 index 0000000..3920d55 --- /dev/null +++ b/data/sync/configs/20260812-tag-deploy-rpm-matrix.yaml @@ -0,0 +1,73 @@ +--- +# Roll out the reworked tag-and-release workflows (PR #44 + issue #84): +# +# - tag_deploy.yml: surface the Forge API response on failed publishes, +# preserve the built module archive (workflow artifact + release +# asset), and dispatch release_rpms.yml ONCE with no build-OS +# override (the hardcoded centos7/centos8 matrix was overriding +# #80's el8 default and failing every tag-triggered RPM build) +# - release_rpms.yml: the build-OS matrix now lives here +# (build_container_oses, default el8/el9/el10), with per-release +# work split into a resolve-release job so parallel per-OS legs +# can't race on release creation or asset wipes +# +# Scoped to those two files; both are fleet-uniform, so no +# preserve_blocks are needed (Renovate-managed scalars are preserved as +# always). +# +# Dynamic-inventory session: run with `repolist=github-org` (or point +# the repolists latest.yaml there). NOTE: the simp-* asset repos +# (simp-doc, simp-utils, ...) also carry affected tag_deploy variants +# but are not in the dynamic inventory or permitted types -- they need +# a separate follow-up pass. +puppetsync::plan_config: + puppetsync: + permitted_project_types: + - pupmod + - pupmod_skeleton + plans: + sync: + github_api_delay_seconds: 1 + merge_github_workflows: + files: + - tag_deploy.yml + - release_rpms.yml + 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/20260812-tag-deploy-rpm-matrix + commit_message: | + [puppetsync] Fix tag-triggered RPM builds and harden tag_deploy + + Every tag push has been dispatching two release_rpms.yml runs + hardcoded to the retired centos7/centos8 build containers, so all + tag-triggered RPM builds fail. tag_deploy.yml now dispatches once + with no OS override, and release_rpms.yml builds el8/el9/el10 from + a single build_container_oses input (narrowable on manual runs), + with release resolution split into its own job so the parallel + per-OS legs cannot race on release creation or asset wipes. + + tag_deploy.yml also now surfaces the Puppet Forge API response when + a publish fails (instead of curl --fail discarding it) and keeps + the built module archive as a workflow artifact and release asset. + + github: + pr_user: silug # This should be the account that *submitted* the PRs + # (Used by idempotency checks when approving/merging PRs) + approval_message: ':+1: :ghost:' diff --git a/data/sync/configs/latest.yaml b/data/sync/configs/latest.yaml index 0ea5a01..75af7ed 120000 --- a/data/sync/configs/latest.yaml +++ b/data/sync/configs/latest.yaml @@ -1 +1 @@ -20260811-reference-md.yaml \ No newline at end of file +20260812-tag-deploy-rpm-matrix.yaml \ No newline at end of file