From 027e3b582d52870911033fbf8e3dfd631dd7e7bb Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Wed, 18 Feb 2026 10:37:37 +0100 Subject: [PATCH 1/3] fix(release): retention workflow ohne oidc-fehlpfad stabilisieren --- .github/workflows/release-retention.yml | 8 +------- docs/versioning/003_CHANGELOG_RELEASES.MD | 2 +- docs/versioning/103_CHANGELOG_RELEASES.MD | 2 +- tools/ci/release/retention_apply.sh | 10 ++++++++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release-retention.yml b/.github/workflows/release-retention.yml index 04dcca8..4ae1a57 100644 --- a/.github/workflows/release-retention.yml +++ b/.github/workflows/release-retention.yml @@ -11,7 +11,6 @@ on: permissions: contents: write packages: write - id-token: write jobs: retention: @@ -29,11 +28,6 @@ jobs: dotnet-version: | 8.0.x 10.0.102 - - name: NuGet login (OIDC / Trusted Publishing) - uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1 - id: nuget_login - with: - user: Tomtastisch - name: Apply retention (GH Releases + NuGet unlist + GH Packages delete) env: GH_TOKEN: ${{ github.token }} @@ -41,7 +35,7 @@ jobs: OWNER: ${{ github.repository_owner }} PACKAGE_ID: Tomtastisch.FileClassifier NUGET_PACKAGE_ID: tomtastisch.fileclassifier - NUGET_API_KEY: ${{ steps.nuget_login.outputs.NUGET_API_KEY || secrets.NUGET_API_KEY }} + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} OUT_DIR: artifacts/retention run: bash tools/ci/release/retention_apply.sh - name: Upload retention artifacts diff --git a/docs/versioning/003_CHANGELOG_RELEASES.MD b/docs/versioning/003_CHANGELOG_RELEASES.MD index d55231e..bafb3af 100644 --- a/docs/versioning/003_CHANGELOG_RELEASES.MD +++ b/docs/versioning/003_CHANGELOG_RELEASES.MD @@ -29,7 +29,7 @@ der Git-Tag `vX.Y.Z` (optional `-prerelease`) als SSOT. - Docs/CI/Tooling: - NuGet-Trusted-Publishing-Doku (DE/EN) und Root-README auf den angepassten Gate-4-Ablauf aktualisiert. - Commit-Referenz fuer Version 5.2.0 in Versionshistorie (DE/EN) hinzugefuegt. - - Retention-Workflow auf OIDC-Key-Fallback (`NuGet/login`) fuer NuGet-Unlist umgestellt. + - Retention-Workflow auf Secret-basiertes NuGet-Unlist (`NUGET_API_KEY`) gehaertet; OIDC bleibt auf `release.yml` beschraenkt. ## [5.1.4] - Changed: diff --git a/docs/versioning/103_CHANGELOG_RELEASES.MD b/docs/versioning/103_CHANGELOG_RELEASES.MD index 679d547..a86e44d 100644 --- a/docs/versioning/103_CHANGELOG_RELEASES.MD +++ b/docs/versioning/103_CHANGELOG_RELEASES.MD @@ -28,7 +28,7 @@ All changes are documented here in technical terms. The release version itself i - Docs/CI/Tooling: - Updated NuGet trusted-publishing docs (DE/EN) and root README for the adjusted Gate 4 behavior. - Added commit reference for version 5.2.0 in version history (DE/EN). - - Switched retention workflow to OIDC key fallback (`NuGet/login`) for NuGet unlist operations. + - Hardened retention workflow to secret-based NuGet unlist (`NUGET_API_KEY`); OIDC remains scoped to `release.yml`. ## [5.1.4] - Changed: diff --git a/tools/ci/release/retention_apply.sh b/tools/ci/release/retention_apply.sh index 0b08acc..ef374c0 100755 --- a/tools/ci/release/retention_apply.sh +++ b/tools/ci/release/retention_apply.sh @@ -68,10 +68,16 @@ mapfile -t NUGET_VERSIONS < <(curl -fsSL "https://api.nuget.org/v3-flatcontainer # GH packages versions (user endpoint by default; fallback org endpoint) PACKAGE_LIST_ENDPOINT="/users/${OWNER}/packages/nuget/${PACKAGE_ID}/versions" -if ! gh api "${PACKAGE_LIST_ENDPOINT}" >/dev/null 2>&1; then +if gh api "${PACKAGE_LIST_ENDPOINT}" >/dev/null 2>&1; then + mapfile -t PACKAGE_ROWS < <(gh api "${PACKAGE_LIST_ENDPOINT}" --paginate --jq '.[] | [.id, .name] | @tsv') +else PACKAGE_LIST_ENDPOINT="/orgs/${OWNER}/packages/nuget/${PACKAGE_ID}/versions" + if gh api "${PACKAGE_LIST_ENDPOINT}" >/dev/null 2>&1; then + mapfile -t PACKAGE_ROWS < <(gh api "${PACKAGE_LIST_ENDPOINT}" --paginate --jq '.[] | [.id, .name] | @tsv') + else + PACKAGE_ROWS=() + fi fi -mapfile -t PACKAGE_ROWS < <(gh api "${PACKAGE_LIST_ENDPOINT}" --paginate | jq -r '.[] | [.id, .name] | @tsv' || true) { echo '{' From 83a4d0be5a7d60e64791dbfe54cf22a786fe444b Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Wed, 18 Feb 2026 10:41:33 +0100 Subject: [PATCH 2/3] chore(ci): preflight mit aktualisiertem pr-body neu triggern From 5ab302a65b37565adb374da11b39e79b0c2e05e8 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Agent Date: Wed, 18 Feb 2026 10:48:00 +0100 Subject: [PATCH 3/3] fix(release): gh-packages retention fail-closed und ohne doppelaufruf --- tools/ci/release/retention_apply.sh | 47 ++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/tools/ci/release/retention_apply.sh b/tools/ci/release/retention_apply.sh index ef374c0..1bbc4d2 100755 --- a/tools/ci/release/retention_apply.sh +++ b/tools/ci/release/retention_apply.sh @@ -67,15 +67,48 @@ mapfile -t RELEASE_ROWS < <(gh api "/repos/${REPO}/releases" --paginate | jq -r mapfile -t NUGET_VERSIONS < <(curl -fsSL "https://api.nuget.org/v3-flatcontainer/${NUGET_PACKAGE_ID}/index.json" | jq -r '.versions[]' || true) # GH packages versions (user endpoint by default; fallback org endpoint) -PACKAGE_LIST_ENDPOINT="/users/${OWNER}/packages/nuget/${PACKAGE_ID}/versions" -if gh api "${PACKAGE_LIST_ENDPOINT}" >/dev/null 2>&1; then - mapfile -t PACKAGE_ROWS < <(gh api "${PACKAGE_LIST_ENDPOINT}" --paginate --jq '.[] | [.id, .name] | @tsv') +PACKAGE_ROWS=() +PACKAGE_LIST_ENDPOINT="" +fetch_package_rows() { + local endpoint="${1}" + local out_file err_file rc + out_file="$(mktemp)" + err_file="$(mktemp)" + if gh api "${endpoint}" --paginate --jq '.[] | [.id, .name] | @tsv' >"${out_file}" 2>"${err_file}"; then + mapfile -t PACKAGE_ROWS < "${out_file}" + rm -f "${out_file}" "${err_file}" + PACKAGE_LIST_ENDPOINT="${endpoint}" + return 0 + else + rc=$? + fi + if grep -Eqi '(404|not found)' "${err_file}"; then + rm -f "${out_file}" "${err_file}" + return 4 + fi + echo "FAIL: gh api failed for package list endpoint ${endpoint} (rc=${rc})" >&2 + cat "${err_file}" >&2 + rm -f "${out_file}" "${err_file}" + return "${rc}" +} + +if fetch_package_rows "/users/${OWNER}/packages/nuget/${PACKAGE_ID}/versions"; then + : else - PACKAGE_LIST_ENDPOINT="/orgs/${OWNER}/packages/nuget/${PACKAGE_ID}/versions" - if gh api "${PACKAGE_LIST_ENDPOINT}" >/dev/null 2>&1; then - mapfile -t PACKAGE_ROWS < <(gh api "${PACKAGE_LIST_ENDPOINT}" --paginate --jq '.[] | [.id, .name] | @tsv') + rc=$? + if [[ "${rc}" -eq 4 ]]; then + if fetch_package_rows "/orgs/${OWNER}/packages/nuget/${PACKAGE_ID}/versions"; then + : + else + rc=$? + if [[ "${rc}" -eq 4 ]]; then + echo "INFO: GH Packages endpoint not found for ${PACKAGE_ID}; skipping GH Packages retention" >&2 + else + exit "${rc}" + fi + fi else - PACKAGE_ROWS=() + exit "${rc}" fi fi