From 4bf1b7ac081064b406552726c7aad77b2081c061 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 4 Sep 2025 05:53:28 +0500 Subject: [PATCH 1/9] Add workflow to automatically move Dependabot PRs to Code Review --- .../move-dependency-pr-to-code-review.yml | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 .github/workflows/move-dependency-pr-to-code-review.yml diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml new file mode 100644 index 0000000000..e829dc2792 --- /dev/null +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -0,0 +1,139 @@ +name: Auto-move Dependabot PRs to Code Review + +on: + pull_request: + types: [opened] + +jobs: + move-pr-to-project: + runs-on: ubuntu-latest + if: github.event.pull_request.user.login == 'dependabot[bot]' + steps: + - name: Move PR to Code Review in Project v2 + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const projectNumber = 8; // for "OFN Delivery board" + const org = context.repo.owner; + const repo = context.repo.repo; + const prNumber = context.payload.pull_request.number; + const statusFieldName = "Status"; + const statusValue = "Code review 🔎"; + + // ---- Helper: Get PR Node ID ---- + async function getPrNodeId(owner, repo, number) { + const res = await github.graphql(` + query($owner: String!, $repo: String!, $number: Int!) { + repository(owner: $owner, name: $repo) { + pullRequest(number: $number) { + id + number + title + } + } + } + `, { owner, repo, number }); + return res.repository.pullRequest.id; + } + + console.log("🚀 Starting ProjectV2 automation..."); + + // ---- Step 1: Get Project and Fields ---- + const projectRes = await github.graphql(` + query($org: String!, $number: Int!) { + organization(login: $org) { + projectV2(number: $number) { + id + title + fields(first: 50) { + nodes { + ... on ProjectV2Field { + id + name + } + ... on ProjectV2SingleSelectField { + id + name + options { + id + name + } + } + } + } + } + } + } + `, { org, number: projectNumber }); + + const project = projectRes.organization.projectV2; + if (!project) throw new Error(`❌ Project #${projectNumber} not found`); + + console.log(`✅ Found project: ${project.title} (${project.id})`); + + const statusField = project.fields.nodes.find(f => f.name === statusFieldName); + if (!statusField) throw new Error(`❌ Field '${statusFieldName}' not found`); + + const option = statusField.options.find(o => o.name === statusValue); + if (!option) throw new Error(`❌ Option '${statusValue}' not found in '${statusFieldName}'`); + + console.log(`✅ Found field '${statusFieldName}' and option '${statusValue}'`); + + // ---- Step 2: Get PR Node ID ---- + const prNodeId = await getPrNodeId(org, repo, prNumber); + console.log(`✅ PR #${prNumber} node ID: ${prNodeId}`); + + // ---- Step 3: Check if PR is already in Project ---- + const itemRes = await github.graphql(` + query($prId: ID!) { + node(id: $prId) { + ... on PullRequest { + projectItems(first: 50) { + nodes { + id + project { id title } + } + } + } + } + } + `, { prId: prNodeId }); + + let projectItem = itemRes.node.projectItems.nodes.find(i => i.project.id === project.id); + + if (!projectItem) { + console.log("â„šī¸ PR not yet in project, adding..."); + const addRes = await github.graphql(` + mutation($projectId: ID!, $contentId: ID!) { + addProjectV2ItemById(input: {projectId: $projectId, contentId: $contentId}) { + item { id } + } + } + `, { projectId: project.id, contentId: prNodeId }); + projectItem = addRes.addProjectV2ItemById.item; + console.log(`✅ Added PR to project: ${projectItem.id}`); + } else { + console.log(`â„šī¸ PR already in project: ${projectItem.id}`); + } + + // ---- Step 4: Update Status ---- + await github.graphql(` + mutation($projectId: ID!, $itemId: ID!, $fieldId: ID!, $optionId: String!) { + updateProjectV2ItemFieldValue(input: { + projectId: $projectId, + itemId: $itemId, + fieldId: $fieldId, + value: { singleSelectOptionId: $optionId } + }) { + projectV2Item { id } + } + } + `, { + projectId: project.id, + itemId: projectItem.id, + fieldId: statusField.id, + optionId: option.id, + }); + + console.log(`🎉 Moved PR #${prNumber} → '${statusValue}'`); From 9f396a40b7a072eec3f5f74cf352784368a2a35d Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 4 Sep 2025 05:53:48 +0500 Subject: [PATCH 2/9] Update condition to move Dependabot PRs to Code Review for bump titles --- .github/workflows/move-dependency-pr-to-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml index e829dc2792..6584c88622 100644 --- a/.github/workflows/move-dependency-pr-to-code-review.yml +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -7,7 +7,7 @@ on: jobs: move-pr-to-project: runs-on: ubuntu-latest - if: github.event.pull_request.user.login == 'dependabot[bot]' + if: github.event.pull_request.user.login == 'dependabot[bot]' || startsWith(github.event.pull_request.title, 'Bump') steps: - name: Move PR to Code Review in Project v2 uses: actions/github-script@v7 From 1654bb2b0aeefc3ca249e2aa64475cf0b29663a4 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 4 Sep 2025 05:57:40 +0500 Subject: [PATCH 3/9] Rename job from 'move-pr-to-project' to 'move-pr-to-code-review' for clarity --- .github/workflows/move-dependency-pr-to-code-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml index 6584c88622..034df7b38c 100644 --- a/.github/workflows/move-dependency-pr-to-code-review.yml +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -5,7 +5,7 @@ on: types: [opened] jobs: - move-pr-to-project: + move-pr-to-code-review: runs-on: ubuntu-latest if: github.event.pull_request.user.login == 'dependabot[bot]' || startsWith(github.event.pull_request.title, 'Bump') steps: From 17a85e9c1c34985f988f26b864f5be67fbbe8e1f Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 18 Sep 2025 03:00:43 +0500 Subject: [PATCH 4/9] Update GitHub Actions workflow to use specific Dependabot token and set organization name explicitly --- .github/workflows/move-dependency-pr-to-code-review.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml index 034df7b38c..eed1714d01 100644 --- a/.github/workflows/move-dependency-pr-to-code-review.yml +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -12,10 +12,10 @@ jobs: - name: Move PR to Code Review in Project v2 uses: actions/github-script@v7 with: - github-token: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.DEPENDABOT_PR_AUTOMATION_TOKEN }} script: | const projectNumber = 8; // for "OFN Delivery board" - const org = context.repo.owner; + const org = "openfoodfoundation"; const repo = context.repo.repo; const prNumber = context.payload.pull_request.number; const statusFieldName = "Status"; From 28ab41c47f0a7984fd884f9829ff00cd1393a42f Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Thu, 18 Sep 2025 03:17:22 +0500 Subject: [PATCH 5/9] Potential fix for code scanning alert no. 253: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .github/workflows/move-dependency-pr-to-code-review.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml index eed1714d01..18fa5b4857 100644 --- a/.github/workflows/move-dependency-pr-to-code-review.yml +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -1,4 +1,8 @@ name: Auto-move Dependabot PRs to Code Review +permissions: + contents: read + pull-requests: write + project: write on: pull_request: From 782f813a15726b580e7dfb75c71d6824ae2265a0 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Mon, 29 Sep 2025 11:35:48 +0500 Subject: [PATCH 6/9] Add Dependabot PR test event and update workflow for token generation --- .github/test-events/dependabot-pr.json | 15 +++++++++++++++ .../move-dependency-pr-to-code-review.yml | 19 +++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 .github/test-events/dependabot-pr.json diff --git a/.github/test-events/dependabot-pr.json b/.github/test-events/dependabot-pr.json new file mode 100644 index 0000000000..585eded46c --- /dev/null +++ b/.github/test-events/dependabot-pr.json @@ -0,0 +1,15 @@ +{ + "pull_request": { + "number": 13545, + "title": "Bump test from 7.0.4 to 7.0.8", + "user": { + "login": "dependabot[bot]" + } + }, + "repository": { + "owner": { + "login": "openfoodfoundation" + }, + "name": "openfoodnetwork" + } +} diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml index 18fa5b4857..b3ea57dd92 100644 --- a/.github/workflows/move-dependency-pr-to-code-review.yml +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -1,8 +1,4 @@ name: Auto-move Dependabot PRs to Code Review -permissions: - contents: read - pull-requests: write - project: write on: pull_request: @@ -13,15 +9,22 @@ jobs: runs-on: ubuntu-latest if: github.event.pull_request.user.login == 'dependabot[bot]' || startsWith(github.event.pull_request.title, 'Bump') steps: + - name: Generate GitHub App Token + id: app-token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.DEPENDABOT_PR_APP_ID }} + private_key: ${{ secrets.DEPENDABOT_PR_APP_PRIVATE_KEY }} + - name: Move PR to Code Review in Project v2 uses: actions/github-script@v7 with: - github-token: ${{ secrets.DEPENDABOT_PR_AUTOMATION_TOKEN }} + github-token: ${{ steps.app-token.outputs.token }} script: | const projectNumber = 8; // for "OFN Delivery board" - const org = "openfoodfoundation"; - const repo = context.repo.repo; - const prNumber = context.payload.pull_request.number; + const org = "openfoodfoundation"; + const repo = context.repo.repo; + const prNumber = context.payload.pull_request.number; const statusFieldName = "Status"; const statusValue = "Code review 🔎"; From 4a5938c0f7640fb0f84d2d865d7c34c4af6518b6 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Sat, 4 Oct 2025 18:50:47 +0500 Subject: [PATCH 7/9] Add installation retrieval mode and payload for Dependabot token generation --- .github/workflows/move-dependency-pr-to-code-review.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml index b3ea57dd92..5fcbc04b4e 100644 --- a/.github/workflows/move-dependency-pr-to-code-review.yml +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -15,6 +15,8 @@ jobs: with: app_id: ${{ secrets.DEPENDABOT_PR_APP_ID }} private_key: ${{ secrets.DEPENDABOT_PR_APP_PRIVATE_KEY }} + installation_retrieval_mode: id + installation_retrieval_payload: ${{ secrets.DEPENDABOT_PR_APP_INSTALLATION_ID }} - name: Move PR to Code Review in Project v2 uses: actions/github-script@v7 From 9f5d73184fe2378f5a0d7e9699231cff991cae18 Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Sat, 4 Oct 2025 19:24:07 +0500 Subject: [PATCH 8/9] Add .secrets file to define GitHub secrets values locally --- .gitignore | 1 + .secrets.example | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 .secrets.example diff --git a/.gitignore b/.gitignore index 7e6c741b5c..e1c303d217 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ yarn-debug.log* /config/credentials.yml.enc /config/master.key +.secrets diff --git a/.secrets.example b/.secrets.example new file mode 100644 index 0000000000..d1febf16f0 --- /dev/null +++ b/.secrets.example @@ -0,0 +1,4 @@ +# .secrets file define github secrets value locally +DEPENDABOT_PR_APP_ID=123456 +DEPENDABOT_PR_APP_INSTALLATION_ID=123456 +DEPENDABOT_PR_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n....\n-----END RSA PRIVATE KEY-----" \ No newline at end of file From 2c4df63879083925d8a4dff510997a4cf46778ee Mon Sep 17 00:00:00 2001 From: Ahmed Ejaz Date: Mon, 6 Oct 2025 03:35:57 +0500 Subject: [PATCH 9/9] Add permissions for contents, pull-requests, and project in workflow --- .github/workflows/move-dependency-pr-to-code-review.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/move-dependency-pr-to-code-review.yml b/.github/workflows/move-dependency-pr-to-code-review.yml index 5fcbc04b4e..533ed122cc 100644 --- a/.github/workflows/move-dependency-pr-to-code-review.yml +++ b/.github/workflows/move-dependency-pr-to-code-review.yml @@ -1,4 +1,8 @@ name: Auto-move Dependabot PRs to Code Review +permissions: + contents: read + pull-requests: read + project: write on: pull_request: