From 374375ae9bf64d6b2f4846f97b94382201dd4c47 Mon Sep 17 00:00:00 2001 From: Nil MALHOMME Date: Wed, 8 Jul 2026 23:11:13 +0200 Subject: [PATCH 1/5] feat: Switched to centralised GH Actions --- .github/workflows/changelog.yml | 155 +----------- .github/workflows/dependency-review.yml | 49 +--- .github/workflows/release.yml | 302 +++--------------------- .github/workflows/stale.yml | 53 +---- 4 files changed, 40 insertions(+), 519 deletions(-) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index c728d6c..481cd61 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -14,160 +14,19 @@ name: Changelog on: push: - branches: [ main ] + branches: [main] paths-ignore: - - "CHANGELOG.md" # don't re-trigger after the bot commit + - "CHANGELOG.md" - "**.md" - "LICENSE" pull_request: - branches: [ main ] + branches: [main] paths-ignore: - "CHANGELOG.md" - "LICENSE" -permissions: - contents: read - pull-requests: read - -# ────────────────────────────────────────────────────────────── jobs: - - # ── Update CHANGELOG.md on main ─────────────────────────── - update-changelog: - name: 📝 Update CHANGELOG.md - runs-on: ubuntu-latest - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - permissions: - contents: read # KTESTIFY_CHANGELOG_PAT handles the push to main - pull-requests: read # fetch PR metadata for git-cliff - - steps: - - name: Checkout (full history for cliff) - uses: actions/checkout@v7 - with: - fetch-depth: 0 - token: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} - - - name: Generate CHANGELOG.md with git-cliff - uses: orhun/git-cliff-action@v4 - with: - config: cliff.toml - env: - OUTPUT: CHANGELOG.md - GITHUB_REPO: ${{ github.repository }} - GITHUB_TOKEN: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} - - - name: Commit updated CHANGELOG.md - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - # Only commit if the file actually changed - if git diff --quiet CHANGELOG.md; then - echo "CHANGELOG.md is already up-to-date — nothing to commit." - else - git add CHANGELOG.md - git commit -m "chore(release): update CHANGELOG.md [skip ci]" - git push - fi - - # ── PR preview (read-only, no push) ─────────────────────── - preview-changelog: - name: 🔍 Preview changelog (unreleased) - runs-on: ubuntu-latest - if: github.event_name == 'pull_request' - permissions: - contents: read - pull-requests: write # post / update the sticky preview comment - - steps: - - name: Checkout (full history for cliff) - uses: actions/checkout@v7 - with: - fetch-depth: 0 - - - name: Generate unreleased changelog preview - uses: orhun/git-cliff-action@v4 - with: - config: cliff.toml - # Only show unreleased (since last tag) - args: --verbose --unreleased - env: - OUTPUT: CHANGELOG-preview.md - GITHUB_REPO: ${{ github.repository }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload preview artifact - uses: actions/upload-artifact@v7 - with: - name: changelog-preview-${{ github.run_id }} - path: CHANGELOG-preview.md - retention-days: 7 - - # ── Write preview to job summary ───────────────────── - - name: 📋 Write changelog preview to job summary - run: | - echo "## 📋 Unreleased Changelog Preview" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - if [ -s CHANGELOG-preview.md ]; then - cat CHANGELOG-preview.md >> $GITHUB_STEP_SUMMARY - else - echo "_No unreleased changes found since the last tag._" >> $GITHUB_STEP_SUMMARY - fi - - # ── Sticky PR comment ───────────────────────────────── - # Updates the same comment on every push to keep the PR clean. - - name: 💬 Post changelog preview to PR - uses: actions/github-script@v9 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const fs = require('fs'); - const marker = ''; - const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; - - let preview = '_No unreleased changes found since the last tag._'; - if (fs.existsSync('CHANGELOG-preview.md')) { - const raw = fs.readFileSync('CHANGELOG-preview.md', 'utf8').trim(); - if (raw.length > 0) preview = raw; - } - - const body = [ - marker, - '## 📋 Unreleased Changelog Preview', - '', - '> This is what the next release notes will look like based on commits in this PR.', - '', - preview, - '', - '---', - `*🔄 [Run #${process.env.GITHUB_RUN_NUMBER}](${runUrl}) · ${new Date().toUTCString()}*`, - ].join('\n'); - - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - per_page: 100, - }); - - const existing = comments.find(c => c.body?.includes(marker)); - - if (existing) { - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: existing.id, - body, - }); - console.log(`✅ Updated changelog preview comment #${existing.id}`); - } else { - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body, - }); - console.log('✅ Created changelog preview comment'); - } - - + changelog: + uses: ktestify/.github/.github/workflows/reusable-changelog.yml@main + secrets: + KTESTIFY_CHANGELOG_PAT: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index e1d4f66..3c585b1 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -12,51 +12,8 @@ name: Dependency Review on: pull_request: - branches: [ main ] + branches: [main] -permissions: - contents: read - pull-requests: write # needed to post an inline PR comment - -# ────────────────────────────────────────────────────────────── jobs: - dependency-review: - name: 🔒 Dependency Review - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write # post the summary comment on the PR - - steps: - - name: Checkout - uses: actions/checkout@v7 # v6: credentials stored in $RUNNER_TEMP - - - name: Dependency Review - uses: actions/dependency-review-action@v5 - with: - # Fail the check for any vulnerability rated moderate or above - fail-on-severity: moderate - - # Post a detailed summary as a PR comment - comment-summary-in-pr: always - - # Security checks - vulnerability-check: true - - # Licence checks — allow common open-source-compatible licences - license-check: true - allow-licenses: >- - Apache-2.0, - MIT, - BSD-2-Clause, - BSD-3-Clause, - ISC, - LGPL-2.0-only, - LGPL-2.1-only, - LGPL-2.1-or-later, - EPL-1.0, - EPL-2.0, - CDDL-1.0, - CC0-1.0 - - + review: + uses: ktestify/.github/.github/workflows/reusable-dependency-review.yml@main diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9f02274..52b0221 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,288 +1,44 @@ # ============================================================ -# Release — Publish to Maven Central +# Release — Publish ktestify-core to Maven Central # -# Workflow: -# 1. Developer triggers this workflow manually and provides: -# • release version (e.g. 0.3.0) -# • next dev version (e.g. 0.3.1-SNAPSHOT) -# 2. Release version is set in pom.xml via `versions:set`. -# 3. Full build runs with the `release` Maven profile -# (GPG signing + central-publishing-maven-plugin). -# 4. Artifact is published to Maven Central. -# 5. Git is tagged and pom.xml is bumped to next SNAPSHOT. -# 6. A GitHub Release is created with auto-generated notes. -# -# Required secrets (set in Settings → Secrets → Actions): -# KTESTIFY_CHANGELOG_PAT — PAT with repo scope; used for checkout, git push, -# tagging, and GitHub Release creation (bypasses main -# branch ruleset that blocks github-actions[bot]) -# CENTRAL_USERNAME — Maven Central Portal username token -# CENTRAL_PASSWORD — Maven Central Portal password token -# GPG_PRIVATE_KEY — ASCII-armored GPG private key -# GPG_PASSPHRASE — Passphrase for the GPG key -# -# The job runs inside a `release` GitHub Environment so a -# mandatory approval gate can be configured there. +# Select a bump type — the reusable workflow calculates +# the release version and next SNAPSHOT automatically. # ============================================================ name: Release on: workflow_dispatch: inputs: - release-version: - description: "Release version — no 'v' prefix, no '-SNAPSHOT' (e.g. 0.3.0)" + bump-type: + description: "Version bump type" required: true - type: string - next-snapshot-version: - description: "Next development version — must end with -SNAPSHOT (e.g. 0.3.1-SNAPSHOT)" - required: true - type: string + type: choice + options: + - bugfix + - minor + - major + - release-candidate dry-run: description: "Dry run — build & sign but skip publish, tag & GitHub Release" required: false - default: "false" - type: choice - options: [ "false", "true" ] - -# FIX 1: Single permissions block — workflow-level removed, declared once at job level. -# pull-requests: read is retained for git-cliff PR metadata fetching. + default: false + type: boolean -env: - JAVA_VERSION: "25" - MAVEN_OPTS: "-Xmx2048m -XX:+EnableDynamicAgentLoading" - -# ────────────────────────────────────────────────────────────── jobs: release: - name: 🚀 Release ${{ inputs.release-version }} - runs-on: ubuntu-latest - environment: release - permissions: - contents: read # KTESTIFY_CHANGELOG_PAT handles all writes to main - id-token: write # OIDC token for Maven Central trusted publishing - pull-requests: read # git-cliff: fetch PR metadata for changelog - - steps: - # ── Input validation ────────────────────────────────── - # IMPROVEMENT: Catch malformed versions before they touch git or pom.xml. - - name: Validate version inputs - run: | - if [[ ! "${{ inputs.release-version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "ERROR: release-version must be X.Y.Z with no 'v' prefix and no '-SNAPSHOT'." - echo " Got: '${{ inputs.release-version }}'" - exit 1 - fi - if [[ ! "${{ inputs.next-snapshot-version }}" =~ ^[0-9]+\.[0-9]+\.[0-9]+-SNAPSHOT$ ]]; then - echo "ERROR: next-snapshot-version must be X.Y.Z-SNAPSHOT." - echo " Got: '${{ inputs.next-snapshot-version }}'" - exit 1 - fi - echo "Versions validated: ${{ inputs.release-version }} → ${{ inputs.next-snapshot-version }}" - - # ── Checkout ────────────────────────────────────────── - - name: Checkout (full history for tagging) - uses: actions/checkout@v7 - with: - token: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} - fetch-depth: 0 - - # ── Java & Maven ────────────────────────────────────── - - name: Set up Java ${{ env.JAVA_VERSION }} - uses: actions/setup-java@v5 - with: - distribution: temurin - java-version: ${{ env.JAVA_VERSION }} - cache: maven - server-id: central - server-username: MAVEN_USERNAME - server-password: MAVEN_PASSWORD - - # ── GPG ─────────────────────────────────────────────── - - name: Import GPG signing key - run: | - echo "${{ secrets.GPG_PRIVATE_KEY }}" | \ - gpg --batch --import --no-tty - KEY_FPR=$(gpg --list-secret-keys --with-colons 2>/dev/null \ - | awk -F: '/^fpr/{print $10; exit}') - echo "${KEY_FPR}:6:" | gpg --import-ownertrust --batch --no-tty - echo "Imported key fingerprint: ${KEY_FPR}" - - # ── Set release version ─────────────────────────────────── - - name: Set pom.xml to release version ${{ inputs.release-version }} - run: | - mvn versions:set \ - -DnewVersion=${{ inputs.release-version }} \ - --no-transfer-progress - mvn versions:commit --no-transfer-progress - - # ── Update README.md with release version ───────────────── - # Two substitutions: - # 1. shields.io version badge — pattern: badge/version--6EE7B7 - # 2. Maven dependency snippet — pattern: - - name: Update README.md to release version ${{ inputs.release-version }} - run: | - RELEASE_VERSION="${{ inputs.release-version }}" - # 1. Version badge (shields.io encodes '-' as '--' in label text) - sed -i -E \ - "s|(badge/version-)([^?]+)(-6EE7B7)|\1${RELEASE_VERSION}\3|" \ - README.md - # 2. Maven tag inside the dependency snippet - sed -i -E \ - "s|()[0-9][^<]*()|\1${RELEASE_VERSION}\2|" \ - README.md - echo "README.md updated → ${RELEASE_VERSION}" - grep -E "badge/version|" README.md | head -5 - - # ── Build, test & sign ──────────────────────────────────── - # FIX 2: GPG passphrase moved from CLI arg to step-level env var. - # Passing secrets as Maven -D flags exposes them in `ps` output and - # runner debug logs. The shell variable ${GPG_PASSPHRASE} is expanded - # at runtime without embedding the secret value in the command string. - - name: Build with release profile (compile + test + GPG sign) - run: | - mvn verify -P release \ - --no-transfer-progress \ - -Dspotless.check.skip=true - env: - TESTCONTAINERS_RYUK_DISABLED: "true" - MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - - # ── Publish ─────────────────────────────────────────── - - name: Publish to Maven Central - if: inputs.dry-run == 'false' - run: | - mvn deploy -P release \ - --no-transfer-progress \ - -DskipTests \ - -Dspotless.check.skip=true - env: - MAVEN_USERNAME: ${{ secrets.CENTRAL_USERNAME }} - MAVEN_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} - - # ── Commit, tag & push ──────────────────────────────── - - name: Commit release version, tag & push - if: inputs.dry-run == 'false' - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add pom.xml README.md - git commit -m "chore(release): prepare release ${{ inputs.release-version }} [skip ci]" - git tag -a "v${{ inputs.release-version }}" \ - -m "Release ${{ inputs.release-version }}" - git push origin main --follow-tags - - # ── Generate release notes with git-cliff ───────────── - - name: Generate release notes (git-cliff) - if: inputs.dry-run == 'false' - uses: orhun/git-cliff-action@v4 - with: - config: cliff.toml - args: --verbose --latest --strip header - env: - OUTPUT: RELEASE_NOTES.md - GITHUB_REPO: ${{ github.repository }} - GITHUB_TOKEN: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} - - # ── Update CHANGELOG.md with the new release ────────── - - name: Update CHANGELOG.md (git-cliff full history) - if: inputs.dry-run == 'false' - uses: orhun/git-cliff-action@v4 - with: - config: cliff.toml - args: --verbose - env: - OUTPUT: CHANGELOG.md - GITHUB_REPO: ${{ github.repository }} - GITHUB_TOKEN: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} - - - name: Bump to next SNAPSHOT ${{ inputs.next-snapshot-version }} - if: inputs.dry-run == 'false' - run: | - mvn versions:set \ - -DnewVersion=${{ inputs.next-snapshot-version }} \ - --no-transfer-progress - mvn versions:commit --no-transfer-progress - - NEXT_SNAPSHOT="${{ inputs.next-snapshot-version }}" - # shields.io encodes '-' as '--', so "0.3.1-SNAPSHOT" → "0.3.1--SNAPSHOT" - NEXT_SNAPSHOT_BADGE=$(echo "${NEXT_SNAPSHOT}" | sed 's/-/--/g') - # 1. Version badge - sed -i -E \ - "s|(badge/version-)([^?]+)(-6EE7B7)|\1${NEXT_SNAPSHOT_BADGE}\3|" \ - README.md - # 2. Maven tag - sed -i -E \ - "s|()[0-9][^<]*()|\1${NEXT_SNAPSHOT}\2|" \ - README.md - echo "README.md updated → ${NEXT_SNAPSHOT}" - - git add pom.xml CHANGELOG.md README.md - git commit -m "chore(release): prepare next iteration ${{ inputs.next-snapshot-version }} [skip ci]" - git push origin main - - # ── GitHub Release ──────────────────────────────────── - - name: Create GitHub Release - if: inputs.dry-run == 'false' - uses: softprops/action-gh-release@v3 - with: - token: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} - tag_name: v${{ inputs.release-version }} - name: "ktestify ${{ inputs.release-version }}" - body_path: RELEASE_NOTES.md - draft: false - prerelease: false - files: | - target/ktestify-core.jar - target/ktestify-core-sources.jar - target/ktestify-core-javadoc.jar - - # ── FIX 3: Rollback on failure ──────────────────────── - # Runs only when a previous step has failed AND this is not a dry-run. - # At this point the tag may or may not have been pushed depending on - # which step failed. Both cases are handled safely. - - name: Rollback on failure - if: failure() && inputs.dry-run == 'false' - run: | - echo "A release step failed — attempting rollback..." - TAG="v${{ inputs.release-version }}" - - # Delete remote tag if it was already pushed - if git ls-remote --tags origin "$TAG" | grep -q "$TAG"; then - git push origin --delete "$TAG" \ - && echo "Deleted remote tag $TAG" \ - || echo "Warning: could not delete remote tag $TAG — delete it manually." - fi - - # Delete local tag if present - git tag -d "$TAG" 2>/dev/null && echo "Deleted local tag $TAG" || true - - # Reset pom.xml, CHANGELOG.md and README.md to HEAD so main is clean - git checkout HEAD -- pom.xml CHANGELOG.md README.md 2>/dev/null || true - - echo "" - echo "Rollback complete." - echo "Review the failure above, fix the root cause, then re-trigger the workflow." - - # ── Dry-run summary ─────────────────────────────────── - - name: Generate dry-run changelog preview - if: inputs.dry-run == 'true' - uses: orhun/git-cliff-action@v4 - with: - config: cliff.toml - args: --verbose --unreleased --bump - env: - OUTPUT: RELEASE_NOTES_DRYRUN.md - GITHUB_REPO: ${{ github.repository }} - GITHUB_TOKEN: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} - - - name: Dry-run summary - if: inputs.dry-run == 'true' - run: | - echo "✅ Dry-run complete — artifacts were built & signed." - echo " Release version : ${{ inputs.release-version }}" - echo " Next SNAPSHOT : ${{ inputs.next-snapshot-version }}" - echo " Nothing was published, tagged, or pushed." - echo "" - echo "📋 Release notes preview:" - cat RELEASE_NOTES_DRYRUN.md \ No newline at end of file + uses: ktestify/.github/.github/workflows/reusable-maven-release.yml@main + with: + bump-type: ${{ inputs.bump-type }} + dry-run: ${{ inputs.dry-run }} + release-name-prefix: "ktestify-core" + update-readme-badge: true + release-artifacts: | + target/ktestify-core.jar + target/ktestify-core-sources.jar + target/ktestify-core-javadoc.jar + secrets: + KTESTIFY_CHANGELOG_PAT: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} + CENTRAL_USERNAME: ${{ secrets.CENTRAL_USERNAME }} + CENTRAL_PASSWORD: ${{ secrets.CENTRAL_PASSWORD }} + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 3a96733..0337029 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -20,57 +20,6 @@ on: - cron: "0 1 * * *" workflow_dispatch: -permissions: - issues: write - pull-requests: write - -# ────────────────────────────────────────────────────────────── jobs: stale: - name: 🕰️ Mark & close stale items - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - - steps: - - uses: actions/stale@v10 # v10 is the current latest (was v9) - with: - # ── Issues ──────────────────────────────────────── - days-before-issue-stale: 60 - days-before-issue-close: 14 - stale-issue-label: "stale" - stale-issue-message: > - 👋 This issue has been automatically marked as stale because it - has had no activity in the last 60 days. - It will be closed in 14 days if no further activity occurs. - If this is still relevant, please leave a comment or remove - the `stale` label. - close-issue-message: > - 🔒 Closing this issue due to prolonged inactivity. - Feel free to reopen it if the problem resurfaces. - - # ── Pull Requests ───────────────────────────────── - days-before-pr-stale: 30 - days-before-pr-close: 7 - stale-pr-label: "stale" - stale-pr-message: > - 👋 This pull request has been automatically marked as stale - because it has had no activity in the last 30 days. - It will be closed in 7 days if no further activity occurs. - If work is still in progress, please push a commit or leave - a comment. - close-pr-message: > - 🔒 Closing this pull request due to prolonged inactivity. - Please reopen it when you are ready to continue. - - # ── Exemptions ─────────────────────────────────── - exempt-issue-labels: "keep-open,security,pinned,breaking-change" - exempt-pr-labels: "keep-open,security,pinned,work-in-progress" - exempt-all-milestones: true - - # ── Misc ────────────────────────────────────────── - remove-stale-when-updated: true - operations-per-run: 100 - - + uses: ktestify/.github/.github/workflows/reusable-stale.yml@main From a5fe58fd08adf6c23b4c23b11162a06ab37ab8cd Mon Sep 17 00:00:00 2001 From: Nil MALHOMME <31489080+nil-malh@users.noreply.github.com> Date: Wed, 8 Jul 2026 23:20:12 +0200 Subject: [PATCH 2/5] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/changelog.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml index 481cd61..2b2f517 100644 --- a/.github/workflows/changelog.yml +++ b/.github/workflows/changelog.yml @@ -12,6 +12,9 @@ # ============================================================ name: Changelog +permissions: + contents: read + on: push: branches: [main] @@ -27,6 +30,8 @@ on: jobs: changelog: + permissions: + contents: write uses: ktestify/.github/.github/workflows/reusable-changelog.yml@main secrets: KTESTIFY_CHANGELOG_PAT: ${{ secrets.KTESTIFY_CHANGELOG_PAT }} From f1ab3d8f3e4569b645b971a3dc976c7833c046b8 Mon Sep 17 00:00:00 2001 From: Nil MALHOMME <31489080+nil-malh@users.noreply.github.com> Date: Wed, 8 Jul 2026 23:20:21 +0200 Subject: [PATCH 3/5] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 3c585b1..29e16fa 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -14,6 +14,10 @@ on: pull_request: branches: [main] +permissions: + contents: read + pull-requests: read + jobs: review: uses: ktestify/.github/.github/workflows/reusable-dependency-review.yml@main From 29c4cd71a46c6267fd4f260b3c37ede9e4fb56b5 Mon Sep 17 00:00:00 2001 From: Nil MALHOMME <31489080+nil-malh@users.noreply.github.com> Date: Wed, 8 Jul 2026 23:20:28 +0200 Subject: [PATCH 4/5] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 52b0221..3888b6c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,10 @@ # ============================================================ name: Release +permissions: + contents: read + packages: read + on: workflow_dispatch: inputs: From 641bfa12064b2336afa1ab0a0dff1a49d32ec783 Mon Sep 17 00:00:00 2001 From: Nil MALHOMME <31489080+nil-malh@users.noreply.github.com> Date: Wed, 8 Jul 2026 23:20:36 +0200 Subject: [PATCH 5/5] Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 0337029..bc020a8 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -20,6 +20,9 @@ on: - cron: "0 1 * * *" workflow_dispatch: +permissions: + contents: read + jobs: stale: uses: ktestify/.github/.github/workflows/reusable-stale.yml@main