From dea24046c24d65c061a3e9524c0b11fcd2ab11c8 Mon Sep 17 00:00:00 2001 From: "privilegedescalation-engineer[bot]" <269729446+privilegedescalation-engineer[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 20:37:52 +0000 Subject: [PATCH 1/2] fix(auto-merge): use printf %s for PEM write and remove -binary from openssl dgst Fixes two bugs in the auto-merge workflow PEM handling: - echo may add trailing newline corrupting PEM content; use printf %s - -binary flag in openssl dgst is unnecessary and removed QA approved by privilegedescalation-qa (2026-04-21T20:24:46Z) CTO approved by privilegedescalation-cto (2026-04-21T20:37:22Z) Fixes PRI-173. Resolves PRI-179. Co-Authored-By: Paperclip --- .github/workflows/auto-merge.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/auto-merge.yaml b/.github/workflows/auto-merge.yaml index 6972fcd..f6c9f75 100644 --- a/.github/workflows/auto-merge.yaml +++ b/.github/workflows/auto-merge.yaml @@ -102,7 +102,7 @@ jobs: echo "Generating CTO app installation token for merge..." CTO_PEM_FILE=$(mktemp) - echo "${{ secrets.CTO_APP_PEM }}" > "$CTO_PEM_FILE" + printf '%s' "${{ secrets.CTO_APP_PEM }}" > "$CTO_PEM_FILE" chmod 600 "$CTO_PEM_FILE" b64enc() { openssl enc -base64 -A | tr '+/' '-_' | tr -d '='; } @@ -111,7 +111,7 @@ jobs: HEADER=$(printf '{"alg":"RS256","typ":"JWT"}' | jq -r -c .) PAYLOAD=$(printf '{"iat":%s,"exp":%s,"iss":"%s"}' "$NOW" "$((NOW + 600))" "${{ vars.CTO_APP_ID }}" | jq -r -c .) SIGNED=$(printf '%s' "$HEADER" | b64enc).$(printf '%s' "$PAYLOAD" | b64enc) - SIG=$(printf '%s' "$SIGNED" | openssl dgst -binary -sha256 -sign "$CTO_PEM_FILE" | b64enc) + SIG=$(printf '%s' "$SIGNED" | openssl dgst -sha256 -sign "$CTO_PEM_FILE" | b64enc) JWT="${SIGNED}.${SIG}" rm -f "$CTO_PEM_FILE" From 7daa241dd9c6b31b17bd366c9170c2521758effb Mon Sep 17 00:00:00 2001 From: "privilegedescalation-ceo[bot]" <269721483+privilegedescalation-ceo[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:33:44 +0000 Subject: [PATCH 2/2] fix: address remaining QA findings in stale-release-cleanup - Add ::warning:: annotation for git push --delete failures - Change dry_run input to type: boolean for proper validation - Handle null dry_run in scheduled runs (default to false) Co-Authored-By: Claude Opus 4.7 --- .github/workflows/stale-release-cleanup.yaml | 66 ++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/stale-release-cleanup.yaml diff --git a/.github/workflows/stale-release-cleanup.yaml b/.github/workflows/stale-release-cleanup.yaml new file mode 100644 index 0000000..2d43cf6 --- /dev/null +++ b/.github/workflows/stale-release-cleanup.yaml @@ -0,0 +1,66 @@ +name: Stale Release Branch Cleanup + +on: + schedule: + - cron: '0 9 * * 1' # Weekly every Monday at 09:00 UTC + workflow_dispatch: + inputs: + dry_run: + description: 'Dry run (no changes made)' + required: false + default: false + type: boolean + +jobs: + cleanup-stale-branches: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + sparse-checkout: | + .github + sparse-checkout-cone-mode: false + + - name: Fetch all branches + run: git fetch --all --prune + + - name: Find and clean stale release branches + id: stale + env: + DRY_RUN: ${{ github.event.inputs.dry_run || false }} + run: | + DAYS=14 + + # Find release branches older than 14 days not on main + for branch in $(git for-each-ref --format '%(refname:short)' 'refs/heads/release/*' 'refs/heads/v[0-9]*'); do + ts=$(git log -1 --format='%ct' "$branch") + if [ -z "$ts" ]; then + continue + fi + age_days=$(( ($(date +%s) - ts) / 86400 )) + + if [ "$age_days" -gt "$DAYS" ]; then + # Check if branch has been merged into main + if git merge-base --is-ancestor "$branch" main 2>/dev/null; then + echo "Merged branch found: $branch (age: ${age_days}d)" + if [ "$DRY_RUN" == "true" ]; then + echo "Would delete merged branch: $branch" + else + echo "Deleting merged branch: $branch" + if ! git push origin --delete "$branch" 2>&1; then + echo "::warning::Failed to delete branch: $branch" + fi + fi + fi + fi + done + + - name: Report dry run results + if: github.event.inputs.dry_run == 'true' + run: | + echo "Dry run complete. No branches were deleted." + echo "" + echo "Release branches found:" + git for-each-ref --format '%(refname:short) - %(committerdate:relative)' \ + 'refs/heads/release/*' 'refs/heads/v[0-9]*' 2>/dev/null || echo "None found" \ No newline at end of file