From ba32288555c215490c85a1294f4bf6e37c02d978 Mon Sep 17 00:00:00 2001 From: Godwin Rose Samuel Date: Tue, 21 Jan 2025 21:35:15 -0800 Subject: [PATCH] Revert "chore: add project prioritization automation actions (#33043)" This reverts commit ce2fb92d2e78d9b3469552fcc1663ae1c395f0e5. --- .github/workflows/README.md | 15 - .../project-prioritization-assignment.yml | 23 -- .../project-prioritization-r2-assignment.yml | 19 -- .../project-prioritization-r5-assignment.yml | 18 -- .../prioritization/assign-priority.test.js | 237 ---------------- .../prioritization/assign-r2-priority.test.js | 115 -------- .../prioritization/assign-r5-priority.test.js | 116 -------- .../prioritization/helpers/mock-data.js | 257 ------------------ scripts/prioritization/README.md | 115 -------- scripts/prioritization/assign-priority.js | 135 --------- scripts/prioritization/assign-r2-priority.js | 152 ----------- scripts/prioritization/assign-r5-priority.js | 145 ---------- scripts/prioritization/project-api.js | 201 -------------- scripts/prioritization/project-config.js | 65 ----- 14 files changed, 1613 deletions(-) delete mode 100644 .github/workflows/project-prioritization-assignment.yml delete mode 100644 .github/workflows/project-prioritization-r2-assignment.yml delete mode 100644 .github/workflows/project-prioritization-r5-assignment.yml delete mode 100644 scripts/@aws-cdk/script-tests/prioritization/assign-priority.test.js delete mode 100644 scripts/@aws-cdk/script-tests/prioritization/assign-r2-priority.test.js delete mode 100644 scripts/@aws-cdk/script-tests/prioritization/assign-r5-priority.test.js delete mode 100644 scripts/@aws-cdk/script-tests/prioritization/helpers/mock-data.js delete mode 100644 scripts/prioritization/README.md delete mode 100644 scripts/prioritization/assign-priority.js delete mode 100644 scripts/prioritization/assign-r2-priority.js delete mode 100644 scripts/prioritization/assign-r5-priority.js delete mode 100644 scripts/prioritization/project-api.js delete mode 100644 scripts/prioritization/project-config.js diff --git a/.github/workflows/README.md b/.github/workflows/README.md index a963b61de4eb3..c4a166772274e 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -55,11 +55,6 @@ When approved this pushes the PR to the testing pipeline, thus starting the cli integ test build. Owner: Core CDK team -### Initial Priority Assignment - -[project-prioritization-assignment.yml](project-prioritization-assignment.yml): GitHub action for automatically adding PR's with priorities to the project priority board based on their labels. -Owner: CDK Support team - ## Issue Triggered ### Closed Issue Message @@ -108,13 +103,3 @@ Owner: Core CDK team [update-contributors.yml](update-contributors.yml): GitHub action that runs monthly to create a pull request for updating a CONTRIBUTORS file with the top contributors. Owner: Core CDK team - -### R2 Priority Assignment - -[project-prioritization-r2-assignment.yml](project-prioritization-r2-assignment.yml): GitHub action that runs every 6 hours to add PR's to the priority project board that satisfies R2 Priority. -Owner: CDK Support team - -### R5 Priority Assignment - -[project-prioritization-r5-assignment.yml](project-prioritization-r5-assignment.yml): GitHub action that runs every day to add PR's to the priority project board that satisfies R5 Priority. -Owner: CDK Support team diff --git a/.github/workflows/project-prioritization-assignment.yml b/.github/workflows/project-prioritization-assignment.yml deleted file mode 100644 index 5bd0ec706ba53..0000000000000 --- a/.github/workflows/project-prioritization-assignment.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: PR Prioritization -on: - pull_request: - types: - - labeled - - opened - - reopened - - synchronize - - ready_for_review - - -jobs: - prioritize: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Add PR to Project & Set Priority - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.PROJEN_GITHUB_TOKEN }} - script: | - const script = require('./scripts/prioritization/assign-priority.js') - await script({github, context}) diff --git a/.github/workflows/project-prioritization-r2-assignment.yml b/.github/workflows/project-prioritization-r2-assignment.yml deleted file mode 100644 index d61c28b7f9175..0000000000000 --- a/.github/workflows/project-prioritization-r2-assignment.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: PR Prioritization R2 Check -on: - schedule: - - cron: '0 */6 * * 1-5' # Runs every 6 hours during weekdays - workflow_dispatch: # Manual trigger - -jobs: - update_project_status: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Check and assign R2 Priority to PRs - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.PROJEN_GITHUB_TOKEN }} - script: | - const script = require('./scripts/prioritization/assign-r2-priority.js') - await script({github}) diff --git a/.github/workflows/project-prioritization-r5-assignment.yml b/.github/workflows/project-prioritization-r5-assignment.yml deleted file mode 100644 index 300e12fa80b34..0000000000000 --- a/.github/workflows/project-prioritization-r5-assignment.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: PR Prioritization R5 Check -on: - schedule: - - cron: '0 6 * * 1-5' # Runs at 6AM every day during weekdays - workflow_dispatch: # Manual trigger - -jobs: - update_project_status: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Check and Assign R5 Priority to PRs - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.PROJEN_GITHUB_TOKEN }} - script: | - const script = require('./scripts/prioritization/assign-r5-priority.js') - await script({github}) \ No newline at end of file diff --git a/scripts/@aws-cdk/script-tests/prioritization/assign-priority.test.js b/scripts/@aws-cdk/script-tests/prioritization/assign-priority.test.js deleted file mode 100644 index d77a9eaccc937..0000000000000 --- a/scripts/@aws-cdk/script-tests/prioritization/assign-priority.test.js +++ /dev/null @@ -1,237 +0,0 @@ -const { PRIORITIES, LABELS, STATUS, ...PROJECT_CONFIG} = require('../../../../scripts/prioritization/project-config'); -const { - createMockPR, - createMockGithub, - OPTION_IDS -} = require('./helpers/mock-data'); - -const assignPriority = require('../../../../scripts/prioritization/assign-priority'); - - -describe('Priority Assignment (R1, R3, R4)', () => { - let mockGithub; - let mockContext; - - beforeEach(() => { - mockGithub = createMockGithub(); - jest.clearAllMocks(); - }); - - async function verifyProjectState(expectedPriority, expectedStatus) { - const calls = mockGithub.graphql.mock.calls; - - if (!expectedPriority) { - const priorityUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.priorityFieldId - ); - expect(priorityUpdateCall).toBeUndefined(); - return; - } - - const priorityUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.priorityFieldId - ); - const statusUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.statusFieldId - ); - - // Verify priority was set correctly - expect(priorityUpdateCall[1].input.value.singleSelectOptionId) - .toBe(OPTION_IDS[expectedPriority]); - - // Verify status was set to Ready - expect(statusUpdateCall[1].input.value.singleSelectOptionId) - .toBe(OPTION_IDS[expectedStatus]); - } - - describe('R1 Priority Tests', () => { - test('should assign R1 and Ready status to non-draft PR with contribution/core label', async () => { - const pr = createMockPR({ - draft: false, - labels: [LABELS.CORE] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R1, STATUS.READY); - }); - - test('should assign R1 and Ready status to non-draft PR with contribution/core and needs-maintainer-review labels', async () => { - const pr = createMockPR({ - draft: false, - labels: [LABELS.CORE, LABELS.MAINTAINER_REVIEW] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R1, STATUS.READY); - }); - - test('should not add draft PR with contribution/core label to project', async () => { - const pr = createMockPR({ - draft: true, - labels: [LABELS.CORE] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(null); - }); - }); - - describe('R3 Priority Tests', () => { - test('should assign R3 and Ready status to non-draft PR with needs-maintainer-review label', async () => { - const pr = createMockPR({ - draft: false, - labels: [LABELS.MAINTAINER_REVIEW] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R3, STATUS.READY); - }); - - test('should not assign R3 to draft PR with needs-maintainer-review label', async () => { - const pr = createMockPR({ - draft: true, - labels: [LABELS.MAINTAINER_REVIEW] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(null); - }); - }); - - describe('R4 Priority Tests', () => { - test('should assign R4 and Ready status to PR with pr/reviewer-clarification-requested and needs-community-review labels', async () => { - const pr = createMockPR({ - draft: true, - labels: [ - LABELS.CLARIFICATION_REQUESTED, - LABELS.COMMUNITY_REVIEW - ] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R4, STATUS.READY); - }); - - test('should assign R4 and Ready status to PR with pr-linter/exemption-requested and needs-community-review labels', async () => { - const pr = createMockPR({ - draft: true, - labels: [ - LABELS.EXEMPTION_REQUESTED, - LABELS.COMMUNITY_REVIEW - ] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R4, STATUS.READY); - }); - - test('should assign R4 and Ready status to PR with pr/reviewer-clarification-requested and needs-maintainer-review labels', async () => { - const pr = createMockPR({ - draft: true, - labels: [ - LABELS.CLARIFICATION_REQUESTED, - LABELS.MAINTAINER_REVIEW - ] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R4, STATUS.READY); - }); - - test('should assign R4 and Ready status to PR with pr-linter/exemption-requested and needs-maintainer-review labels', async () => { - const pr = createMockPR({ - labels: [ - LABELS.EXEMPTION_REQUESTED, - LABELS.MAINTAINER_REVIEW - ] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R4, STATUS.READY); - }); - - test('should assign R4 and Ready status to PR with pr/reviewer-clarification-requested label and no review labels', async () => { - const pr = createMockPR({ - labels: [LABELS.CLARIFICATION_REQUESTED] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R4, STATUS.READY); - }); - - test('should assign R4 and Ready status to PR with pr-linter/exemption-requested label and no review labels', async () => { - const pr = createMockPR({ - draft: true, - labels: [LABELS.EXEMPTION_REQUESTED] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R4, STATUS.READY); - }); - }); - - describe('Priority Precedence Tests', () => { - test('should assign R1 over R3 when PR has both contribution/core and needs-maintainer-review labels', async () => { - const pr = createMockPR({ - draft: false, - labels: [ - LABELS.CORE, - LABELS.MAINTAINER_REVIEW - ] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R1, STATUS.READY); - }); - - test('should assign R1 over R4 when PR has both contribution/core and pr/reviewer-clarification-requested labels', async () => { - const pr = createMockPR({ - draft: false, - labels: [ - LABELS.CORE, - LABELS.CLARIFICATION_REQUESTED - ] - }); - - mockContext = { payload: { pull_request: pr } }; - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(PRIORITIES.R1, STATUS.READY); - }); - - test('should not assign any priority when no matching labels', async () => { - const pr = createMockPR({ - draft: false, - labels: [] - }); - - mockContext = { payload: { pull_request: pr } }; - - await assignPriority({ github: mockGithub, context: mockContext }); - await verifyProjectState(null); - }); - }); -}); \ No newline at end of file diff --git a/scripts/@aws-cdk/script-tests/prioritization/assign-r2-priority.test.js b/scripts/@aws-cdk/script-tests/prioritization/assign-r2-priority.test.js deleted file mode 100644 index e6c4e1fa309a8..0000000000000 --- a/scripts/@aws-cdk/script-tests/prioritization/assign-r2-priority.test.js +++ /dev/null @@ -1,115 +0,0 @@ -const { PRIORITIES, LABELS, STATUS, ...PROJECT_CONFIG } = require('../../../../scripts/prioritization/project-config'); -const { - createMockGithubForR2, - OPTION_IDS -} = require('./helpers/mock-data'); - -const assignR2Priority = require('../../../../scripts/prioritization/assign-r2-priority'); - -describe('Priority Assignment (R2)', () => { - let mockGithub; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - async function verifyProjectState(expectedPriority, expectedStatus) { - const calls = mockGithub.graphql.mock.calls; - - if (!expectedPriority) { - const priorityUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.priorityFieldId - ); - expect(priorityUpdateCall).toBeUndefined(); - return; - } - - // Get the existing project item data from the mock response - const projectItemResponse = await mockGithub.graphql.mock.results[2].value; - const existingPRData = projectItemResponse.node.projectItems.nodes[0]; - - // Verify priority update - const priorityUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.priorityFieldId - ); - expect(priorityUpdateCall[1].input.value.singleSelectOptionId) - .toBe(OPTION_IDS[expectedPriority]); - - // Find any status update calls - const statusUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.statusFieldId - ); - - if (existingPRData) { - // For existing PR - // Get the existing status - const existingStatus = existingPRData.fieldValues.nodes - .find(node => node.field.name === 'Status')?.name; - - // Verify no status update was made - expect(statusUpdateCall).toBeUndefined(); - - // Verify expected status matches existing status - expect(existingStatus).toBe(expectedStatus); - } else { - // For new PR - expect(statusUpdateCall[1].input.value.singleSelectOptionId) - .toBe(OPTION_IDS[STATUS.READY]); - } - } - - describe('R2 Priority Tests', () => { - test('should assign R2 priority and Ready status to approved PR with failing checks', async () => { - mockGithub = createMockGithubForR2({ - approved: true, - checksState: 'FAILURE' - }); - - await assignR2Priority({ github: mockGithub }); - await verifyProjectState(PRIORITIES.R2, STATUS.READY); - }); - - test('should not assign R2 priority to PR without approval', async () => { - mockGithub = createMockGithubForR2({ - approved: false, - checksState: 'FAILURE' - }); - - await assignR2Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - - test('should not assign R2 priority to PR with passing checks', async () => { - mockGithub = createMockGithubForR2({ - approved: true, - checksState: 'SUCCESS' - }); - - await assignR2Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - - test('should update existing PR to R2 priority', async () => { - mockGithub = createMockGithubForR2({ - approved: true, - checksState: 'FAILURE', - existingPriority: PRIORITIES.R3, - existingStatus: STATUS.IN_PROGRESS - }); - - await assignR2Priority({ github: mockGithub }); - await verifyProjectState(PRIORITIES.R2, STATUS.IN_PROGRESS); - }); - - test('should not update if PR already has R2 priority', async () => { - mockGithub = createMockGithubForR2({ - approved: true, - checksState: 'FAILURE', - existingPriority: PRIORITIES.R2 - }); - - await assignR2Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - }); -}); \ No newline at end of file diff --git a/scripts/@aws-cdk/script-tests/prioritization/assign-r5-priority.test.js b/scripts/@aws-cdk/script-tests/prioritization/assign-r5-priority.test.js deleted file mode 100644 index 1886cc7081b49..0000000000000 --- a/scripts/@aws-cdk/script-tests/prioritization/assign-r5-priority.test.js +++ /dev/null @@ -1,116 +0,0 @@ -const { PRIORITIES, LABELS, STATUS, ...PROJECT_CONFIG } = require('../../../../scripts/prioritization/project-config'); -const { - createMockPR, - createMockGithubForR5, - OPTION_IDS -} = require('./helpers/mock-data'); - -const assignR5Priority = require('../../../../scripts/prioritization/assign-r5-priority'); - -describe('Priority Assignment (R5)', () => { - let mockGithub; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - async function verifyProjectState(expectedPriority, expectedStatus) { - const calls = mockGithub.graphql.mock.calls; - - if (!expectedPriority) { - const priorityUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.priorityFieldId - ); - expect(priorityUpdateCall).toBeUndefined(); - return; - } - - const priorityUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.priorityFieldId - ); - const statusUpdateCall = calls.find(call => - call[1].input?.fieldId === PROJECT_CONFIG.statusFieldId - ); - - expect(priorityUpdateCall[1].input.value.singleSelectOptionId) - .toBe(OPTION_IDS[expectedPriority]); - - expect(statusUpdateCall[1].input.value.singleSelectOptionId) - .toBe(OPTION_IDS[expectedStatus]); - } - - describe('R5 Priority Tests', () => { - test('should assign R5 and Ready status to non-draft PR with needs-community-review label and no updates for 21 days', async () => { - mockGithub = createMockGithubForR5({ - draft: false, - labels: [LABELS.COMMUNITY_REVIEW] - }); - - await assignR5Priority({ github: mockGithub }); - await verifyProjectState(PRIORITIES.R5, STATUS.READY); - }); - - test('should not assign R5 to draft PR with needs-community-review label and no updates for 21 days', async () => { - mockGithub = createMockGithubForR5({ - draft: true, - labels: [LABELS.COMMUNITY_REVIEW] - }); - - await assignR5Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - - test('should not assign R5 if PR updated within 21 days', async () => { - mockGithub = createMockGithubForR5({ - draft: false, - labels: [LABELS.COMMUNITY_REVIEW], - updatedAt: new Date(Date.now() - 20 * 24 * 60 * 60 * 1000).toISOString() - }); - - await assignR5Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - - test('should not assign R5 if PR has needs-community-review and pr/reviewer-clarification-requested labels', async () => { - mockGithub = createMockGithubForR5({ - draft: false, - labels: [LABELS.COMMUNITY_REVIEW, LABELS.CLARIFICATION_REQUESTED] - }); - - await assignR5Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - - test('should not assign R5 if PR has needs-community-review and pr-linter/exemption-requested labels', async () => { - mockGithub = createMockGithubForR5({ - draft: false, - labels: [LABELS.COMMUNITY_REVIEW, LABELS.EXEMPTION_REQUESTED] - }); - - await assignR5Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - - test('should not assign R5 if PR does not have community review label', async () => { - mockGithub = createMockGithubForR5({ - draft: false, - labels: [] - }); - - await assignR5Priority({ github: mockGithub }); - await verifyProjectState(null); - }); - - test('should not update if PR already has R5 priority', async () => { - mockGithub = createMockGithubForR5({ - draft: false, - labels: [LABELS.COMMUNITY_REVIEW], - existingPriority: PRIORITIES.R5 - }); - - await assignR5Priority({ github: mockGithub }); - - await verifyProjectState(null); - }); - }); -}); diff --git a/scripts/@aws-cdk/script-tests/prioritization/helpers/mock-data.js b/scripts/@aws-cdk/script-tests/prioritization/helpers/mock-data.js deleted file mode 100644 index 418194e89ea31..0000000000000 --- a/scripts/@aws-cdk/script-tests/prioritization/helpers/mock-data.js +++ /dev/null @@ -1,257 +0,0 @@ -const { PRIORITIES, LABELS, STATUS, ...PROJECT_CONFIG } = require('../../../../../scripts/prioritization/project-config'); - -const OPTION_IDS = { - [PRIORITIES.R1]: 'r1-option-id', - [PRIORITIES.R2]: 'r2-option-id', - [PRIORITIES.R3]: 'r3-option-id', - [PRIORITIES.R4]: 'r4-option-id', - [PRIORITIES.R5]: 'r5-option-id', - [STATUS.READY]: 'ready-status-id', - [STATUS.IN_PROGRESS]: 'in_progress-status-id', - [STATUS.PAUSED]: 'paused-status-id', - [STATUS.ASSIGNED]: 'assigned-status-id', - [STATUS.DONE]: 'done-status-id' -}; - -const projectFields = { - organization: { - projectV2: { - fields: { - nodes: [ - { - id: PROJECT_CONFIG.priorityFieldId, - name: 'Priority', - options: Object.values(PRIORITIES).map(priority => ({ - id: OPTION_IDS[priority], - name: priority - })) - }, - { - id: PROJECT_CONFIG.statusFieldId, - name: 'Status', - options: Object.values(STATUS).map(status => ({ - id: OPTION_IDS[status], - name: status - })) - } - ] - } - } - } -}; - -const addItemToProject = { - addProjectV2ItemById: { - item: { id: 'new-item-id' } - } -} - -const updateFieldValueInProject = { - updateProjectV2ItemFieldValue: { - projectV2Item: { id: 'new-item-id' } - } -} - -/** - * Creates a mock PR with specified properties - */ -exports.createMockPR = ({ - number = 123, - node_id = 'PR_123', - draft = false, - labels = [], - updatedAt = new Date().toISOString(), - reviews = [], - checksState = 'SUCCESS' -}) => ({ - number, - node_id, - draft, - labels: labels.map(name => ({ name })), - updatedAt, - reviews: { nodes: reviews }, - commits: { - nodes: [{ - commit: { - statusCheckRollup: { state: checksState } - } - }] - } -}); - -/** - * Creates mock GitHub GraphQL client with predefined responses - */ -exports.createMockGithub = () => { - const graphql = jest.fn(); - - graphql - // First call - fetch project fields - .mockResolvedValueOnce(projectFields) - // Second call - add item to project - .mockResolvedValueOnce(addItemToProject) - // Third call - update priority - .mockResolvedValueOnce(updateFieldValueInProject) - // Fourth call - update status - .mockResolvedValueOnce(updateFieldValueInProject); - - return { graphql }; -}; - -/** - * Creates mock GitHub GraphQL client with predefined responses for R5 priority - */ -exports.createMockGithubForR5 = ({ - draft = false, - labels = [], - updatedAt = new Date(Date.now() - 22 * 24 * 60 * 60 * 1000).toISOString(), - existingPriority = null -}) => { - const graphql = jest.fn(); - - // Set up mock responses in sequence - graphql - // First call - fetch open PRs - .mockResolvedValueOnce({ - repository: { - pullRequests: { - nodes: [{ - id: 'PR_123', - number: 123, - draft, - updatedAt, - labels: { - nodes: labels.map(label => ({ name: label })) - } - }], - pageInfo: { - hasNextPage: false, - endCursor: null - } - } - } - }) - // Second call - fetch project fields - .mockResolvedValueOnce(projectFields) - // Third call - fetchProjectItem (check if PR is in project) - .mockResolvedValueOnce({ - node: { - projectItems: { - nodes: existingPriority ? [{ - id: 'existing-item-id', - project: { - id: PROJECT_CONFIG.projectId - }, - fieldValues: { - nodes: [{ - field: { name: 'Priority' }, - name: existingPriority - }] - } - }] : [] - } - } - }) - // Fourth call - add item to project - .mockResolvedValueOnce(addItemToProject) - // Fifth call - update priority - .mockResolvedValueOnce(updateFieldValueInProject) - // Sixth call - update status - .mockResolvedValueOnce(updateFieldValueInProject); - - return { graphql }; -}; - -/** - * Creates mock GitHub GraphQL client with predefined responses for R2 priority - */ -exports.createMockGithubForR2 = ({ - approved = false, - checksState = 'SUCCESS', - existingPriority = null, - existingStatus = STATUS.READY -}) => { - const graphql = jest.fn(); - - // Set up mock responses in sequence - graphql - // First call - fetch open PRs - .mockResolvedValueOnce({ - repository: { - pullRequests: { - nodes: [{ - id: 'PR_123', - number: 123, - reviews: { - nodes: approved ? [ - { state: 'APPROVED' } - ] : [] - }, - commits: { - nodes: [{ - commit: { - statusCheckRollup: { - state: checksState - } - } - }] - } - }], - pageInfo: { - hasNextPage: false, - endCursor: null - } - } - } - }) - // Second call - fetch project fields - .mockResolvedValueOnce(projectFields) - // Third call - check if PR is in project - .mockResolvedValueOnce({ - node: { - projectItems: { - nodes: existingPriority ? [{ - id: 'existing-item-id', - project: { - id: PROJECT_CONFIG.projectId - }, - fieldValues: { - nodes: [ - { - field: { name: 'Priority' }, - name: existingPriority - }, - { - field: { name: 'Status' }, - name: existingStatus - } - ] - } - }] : [] - } - } - }); - - // If PR exists and needs priority update - if (existingPriority && existingPriority !== PRIORITIES.R2) { - // Fourth call - update priority only - graphql.mockResolvedValueOnce({ - updateProjectV2ItemFieldValue: { - projectV2Item: { id: 'existing-item-id' } - } - }); - } - // If PR doesn't exist in project - else if (!existingPriority) { - // Fourth call - add to project - graphql.mockResolvedValueOnce(addItemToProject) - // Fifth call - update priority - .mockResolvedValueOnce(updateFieldValueInProject) - //Sixth call - update status - .mockResolvedValueOnce(updateFieldValueInProject); - } - - return { graphql }; -}; - -exports.OPTION_IDS = OPTION_IDS; \ No newline at end of file diff --git a/scripts/prioritization/README.md b/scripts/prioritization/README.md deleted file mode 100644 index 9d990b0610218..0000000000000 --- a/scripts/prioritization/README.md +++ /dev/null @@ -1,115 +0,0 @@ -# Prioritization Github Action workflow Automation - -## Setup - -Note: This configuration needs to be updated only when project fields are modified. - -### Prerequisites -1. GitHub CLI installed (`gh`) -2. Appropriate permissions to access AWS organization -3. GitHub token with `read:org` and `project` scopes - -### Project Configuration -To set up the prioritization automation, we need to get the field IDs of the project board and update the configuration. Follow these steps: - -1. Add the github token to `GH_TOKEN` environment variable: - - ```bash - export GH_TOKEN="YOUR GITHUB TOKEN" - -2. Retrieve project field IDs for the specific project: - - ```bash - # Get project and field IDs - gh api graphql -f query=' - query { - organization(login: "aws") { - projectV2(number: YOUR PROJECT NUMBER) { - id - fields(first: 20) { - nodes { - ... on ProjectV2SingleSelectField { - id - name - options { - id - name - } - } - } - } - } - } - } - ' | jq '.data.organization.projectV2 as $project | { - projectId: $project.id, - fields: [ - $project.fields.nodes[] | - select(.name == "Priority" or .name == "Status" or .name == "Needs Attention") | - {name: .name, id: .id} - ] - }' - -3. Update configuration with the returned IDs: - - ```javascript - // project-config.js - module.exports = { - ... - projectNumber: 263, // Project Number - projectId: "xxx", // Project ID - priorityFieldId: "xxx", // Priority field ID - statusFieldId: "xxx", // Status field ID - attentionFieldId: "xxx", // Needs Attention field ID - }; - - -## Available Views -1. [Prioritized Backlog](https://github.com/orgs/aws/projects/263/views/1) : Overall view of all PRs with prioritization -2. [My Items](https://github.com/orgs/aws/projects/263/views/6) : Filtered view showing only PRs assigned to you - -## Common Labels and Categories - -### Priority Labels -`R1` -> Non-draft PRs from the team (`contribution/core`) -`R2` -> Approved PRs with failing/pending checks -`R3` -> Non-draft PRs that needs maintainer review (`pr/needs-maintainer-review`) -`R4` -> PRs that needs clarification or exemption (`pr/reviewer-clarification-requested, pr-linter/exemption-requested`), draft state allowed -`R5` -> Non-draft PRs that are in needs-community-review more than 21 days (`pr/needs-community-review`) - -### Work Status Labels -`Ready` -> Means the PR is ready to be picked up for review -`Assigned` -> Means a team member have picked the PR and assigned to themselves -`In progress` -> Currently being reviewed -`Paused` -> PR review is paused for some reason. Eg: security review -`Done` -> PR review is completed and merged or closed - -### Needs Attention Labels -`Extended` -> If the status being in 7-14 days. Taking longer than expected -`Aging` -> If the status being in 14-21 days. Requires immediate attention -`Stalled` -> If the status being in > 21 days. Critical attention required - -These `Needs Attention` states apply to items in the following status labels: -- Ready: Awaiting assignment -- Assigned: Awaiting start -- In Progress: Under review -- Paused: Blocked/On hold - -## Workflows - -### Prioritized Backlog Workflow -1. PRs are automatically categorized by priority (`R1-R5`) -2. Team members can select PRs from the Ready state -3. Status updates flow through: `Assigned` β†’ `In Progress` β†’ `Done/Paused` -4. Time-based monitoring labels are automatically applied in `Needs Attention` based on duration in each state - -### My Items Workflow -1. PRs appear when assigned to you -2. Update status as you progress with reviews -3. Track your active reviews and blocked items -4. Monitor time-based alerts for your assignments - -## Automation -- Priority labels are automatically assigned based on PR labels -- Time-based monitoring states are automatically updated daily -- Status changes trigger automatic label updates \ No newline at end of file diff --git a/scripts/prioritization/assign-priority.js b/scripts/prioritization/assign-priority.js deleted file mode 100644 index b9c232484bfc8..0000000000000 --- a/scripts/prioritization/assign-priority.js +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Handles the initial priority assignment for PRs when labels are added. This script - * processes R1 (team PRs with contribution/core label), R3 (PRs needing maintainer review), - * and R4 (PRs needing clarification or exemption) priorities. When a matching label - * is detected, the PR is added to the project board with appropriate priority and - * set to Ready status. - */ - - -const { PRIORITIES, LABELS, STATUS, ...PROJECT_CONFIG } = require('./project-config'); -const { - updateProjectField, - addItemToProject, - fetchProjectFields, -} = require('./project-api'); - -module.exports = async ({ github, context }) => { - const getPriority = (pr) => { - const labels = pr.labels.map((l) => l.name); - const isDraft = pr.draft === true; - - const hasExemptionOrClarification = labels.some(label => - [LABELS.CLARIFICATION_REQUESTED, LABELS.EXEMPTION_REQUESTED].includes(label) - ); - - // R1: Not draft + contribution/core - if (!isDraft && labels.includes(LABELS.CORE)) { - return PRIORITIES.R1; - } - - // R3: Not draft + needs-maintainer-review + no contribution/core + no exemption/clarification - if (!isDraft && - labels.includes(LABELS.MAINTAINER_REVIEW) && - !labels.includes(LABELS.CORE) && - !hasExemptionOrClarification) { - return PRIORITIES.R3; - } - - // R4: Three conditions (draft allowed) - if (hasExemptionOrClarification && ( - // Condition 1: With community review - labels.includes(LABELS.COMMUNITY_REVIEW) || - // Condition 2: With maintainer review - labels.includes(LABELS.MAINTAINER_REVIEW) || - // Condition 3: No community or maintainer review - (!labels.includes(LABELS.COMMUNITY_REVIEW) && - !labels.includes(LABELS.MAINTAINER_REVIEW)) - )) { - return PRIORITIES.R4; - } - - return null; - }; - - async function addToProject(pr) { - - // Check if PR qualifies for any priority - const priority = getPriority(pr); - if (!priority) { - console.log(`PR #${pr.number} doesn't qualify for any priority. Skipping.`); - return; - } - - console.log(`Processing PR #${pr.number} for ${priority} priority`); - - // Get project fields - const projectFields = await fetchProjectFields({ - github, - org: PROJECT_CONFIG.org, - number: PROJECT_CONFIG.projectNumber - }); - - const priorityField = projectFields.organization.projectV2.fields.nodes.find( - (field) => field.id === PROJECT_CONFIG.priorityFieldId - ); - - const statusField = projectFields.organization.projectV2.fields.nodes.find( - (field) => field.id === PROJECT_CONFIG.statusFieldId - ); - - try { - // Add PR to project - const addResult = await addItemToProject({ - github, - projectId: PROJECT_CONFIG.projectId, - contentId: pr.node_id, - }); - - const itemId = addResult.addProjectV2ItemById.item.id; - - // Set priority - const priorityOptionId = priorityField.options.find( - (option) => option.name === priority - )?.id; - - if (!priorityOptionId) { - console.error(`Priority option ${priority} not found in project settings`); - return; - } - - // Set Ready status - const readyOptionId = statusField.options.find( - (option) => option.name === STATUS.READY - )?.id; - - if (!readyOptionId) { - console.error('Ready status option not found in project settings'); - return; - } - - // Set Priority and Ready Status - await Promise.all([ - updateProjectField({ - github, - projectId: PROJECT_CONFIG.projectId, - itemId: itemId, - fieldId: PROJECT_CONFIG.priorityFieldId, - value: priorityOptionId, - }), - updateProjectField({ - github, - projectId: PROJECT_CONFIG.projectId, - itemId: itemId, - fieldId: PROJECT_CONFIG.statusFieldId, - value: readyOptionId, - }) - ]); - } catch (error) { - console.error(`Error processing PR #${pr.number}:`, error); - } - } - - const pr = context.payload.pull_request; - await addToProject(pr); -}; diff --git a/scripts/prioritization/assign-r2-priority.js b/scripts/prioritization/assign-r2-priority.js deleted file mode 100644 index 0d5379f53a8fa..0000000000000 --- a/scripts/prioritization/assign-r2-priority.js +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Processes open PRs every 6 hours during weekdays to identify and assign R2 priority. A PR qualifies - * for R2 when it has received approval but has failing or pending checks, regardless of its current - * priority or status. These PRs are either added to the project board with R2 priority and Ready status - * (if not already in board) or updated to R2 priority (if already in board with different priority). - */ - -const { PRIORITIES, LABELS, STATUS, ...PROJECT_CONFIG } = require("./project-config"); - -const { - updateProjectField, - addItemToProject, - fetchProjectFields, - fetchOpenPullRequests, - fetchProjectItem, -} = require('./project-api'); - - -module.exports = async ({ github }) => { - let allPRs = []; - let hasNextPage = true; - let cursor = null; - - // Fetch all PRs using pagination - while (hasNextPage) { - const result = await fetchOpenPullRequests({ - github, - owner: PROJECT_CONFIG.owner, - repo: PROJECT_CONFIG.repo, - cursor: cursor, - }); - - const pullRequests = result.repository.pullRequests; - allPRs = allPRs.concat(pullRequests.nodes); - - // Update pagination info - hasNextPage = pullRequests.pageInfo.hasNextPage; - cursor = pullRequests.pageInfo.endCursor; - } - - console.log(`Total PRs fetched: ${allPRs.length}`); - - // Get project fields - const projectFields = await fetchProjectFields({ - github, - org: PROJECT_CONFIG.org, - number: PROJECT_CONFIG.projectNumber - }); - - const priorityField = projectFields.organization.projectV2.fields.nodes.find( - (field) => field.id === PROJECT_CONFIG.priorityFieldId - ); - - const statusField = projectFields.organization.projectV2.fields.nodes.find( - (field) => field.id === PROJECT_CONFIG.statusFieldId - ); - - const r2OptionId = priorityField.options.find( - (option) => option.name === PRIORITIES.R2 - )?.id; - - const readyStatusId = statusField.options.find( - (option) => option.name === STATUS.READY - )?.id; - - for (const pr of allPRs) { - try { - - // Check PR status - const isApproved = pr.reviews.nodes.some( - (review) => review.state === "APPROVED" - ); - - // Skip if PR is not approved - if (!isApproved) { - continue; - } - - // Check status of checks - const checksState = pr.commits.nodes[0]?.commit.statusCheckRollup?.state; - const checksNotPassing = checksState !== "SUCCESS"; - - // Skip if PR checks is not passing - if (!checksNotPassing) { - continue; - } - - console.log(`Processing PR #${pr.number} for ${PRIORITIES.R2} priority consideration`); - - // Get all projects the PR added to - const result = await fetchProjectItem({ - github, - contentId: pr.id - }); - - // Filter our specific project - const projectItem = result.node.projectItems.nodes - .find(item => item.project.id === PROJECT_CONFIG.projectId); - - if (projectItem) { - // PR already in project - const currentPriority = projectItem.fieldValues.nodes - .find(fv => fv.field?.name === 'Priority')?.name; - - if (currentPriority === PRIORITIES.R2) { - console.log(`PR #${pr.number} already has ${PRIORITIES.R2} priority. Skipping.`); - continue; - } - - // Update priority only, maintain existing status - console.log(`Updating PR #${pr.number} from ${currentPriority} to ${PRIORITIES.R2} priority`); - await updateProjectField({ - github, - projectId: PROJECT_CONFIG.projectId, - itemId: projectItem.id, - fieldId: PROJECT_CONFIG.priorityFieldId, - value: r2OptionId, - }); - } else { - // Add new PR to project with R2 priority and Ready status - console.log(`Adding PR #${pr.number} to project with ${PRIORITIES.R2} priority`); - const addResult = await addItemToProject({ - github, - projectId: PROJECT_CONFIG.projectId, - contentId: pr.id, - }); - itemId = addResult.addProjectV2ItemById.item.id; - - // Set both priority and initial status for new items - await Promise.all([ - updateProjectField({ - github, - projectId: PROJECT_CONFIG.projectId, - itemId: itemId, - fieldId: PROJECT_CONFIG.priorityFieldId, - value: r2OptionId, - }), - updateProjectField({ - github, - projectId: PROJECT_CONFIG.projectId, - itemId: itemId, - fieldId: PROJECT_CONFIG.statusFieldId, - value: readyStatusId, - }) - ]); - } - } catch (error) { - console.error(`Error processing PR #${pr.number}:`, error); - continue; - } - } -}; diff --git a/scripts/prioritization/assign-r5-priority.js b/scripts/prioritization/assign-r5-priority.js deleted file mode 100644 index bee4e1921a845..0000000000000 --- a/scripts/prioritization/assign-r5-priority.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Monitors open PRs once daily during weekdays to identify stale community review requests. When a PR - * with the community review label hasn't been updated for the specified threshold - * period (default 21 days), it's assigned R5 priority. These PRs are added to the - * project board and set to Ready status to ensure visibility of long-pending - * community reviews. - */ - -const { PRIORITIES, LABELS, STATUS, DAYS_THRESHOLD, ...PROJECT_CONFIG } = require("./project-config"); - -const { - updateProjectField, - addItemToProject, - fetchProjectFields, - fetchOpenPullRequests, - fetchProjectItem, -} = require('./project-api'); - -const MS_PER_DAY = 1000 * 60 * 60 * 24; - -module.exports = async ({ github }) => { - let allPRs = []; - let hasNextPage = true; - let cursor = null; - - // Fetch all PRs using pagination - while (hasNextPage) { - const result = await fetchOpenPullRequests({ - github, - owner: PROJECT_CONFIG.owner, - repo: PROJECT_CONFIG.repo, - cursor: cursor, - }); - - const pullRequests = result.repository.pullRequests; - allPRs = allPRs.concat(pullRequests.nodes); - - // Update pagination info - hasNextPage = pullRequests.pageInfo.hasNextPage; - cursor = pullRequests.pageInfo.endCursor; - } - - console.log(`Total PRs fetched: ${allPRs.length}`); - - // Get project fields - const projectFields = await fetchProjectFields({ - github, - org: PROJECT_CONFIG.org, - number: PROJECT_CONFIG.projectNumber - }); - - const priorityField = projectFields.organization.projectV2.fields.nodes.find( - (field) => field.id === PROJECT_CONFIG.priorityFieldId - ); - - const statusField = projectFields.organization.projectV2.fields.nodes.find( - (field) => field.id === PROJECT_CONFIG.statusFieldId - ); - - const r5OptionId = priorityField.options.find( - (option) => option.name === PRIORITIES.R5 - )?.id; - - const readyStatusId = statusField.options.find( - (option) => option.name === STATUS.READY - )?.id; - - for (const pr of allPRs) { - const labels = pr.labels.nodes.map((l) => l.name); - const isDraft = pr.draft === true; - - // Skip draft PRs - if (isDraft) { - console.log(`Skipping draft PR #${pr.number}`); - continue; - } - - const hasExemptionOrClarification = labels.some(label => - [LABELS.CLARIFICATION_REQUESTED, LABELS.EXEMPTION_REQUESTED].includes(label) - ); - - // Skip if PR doesn't have community review label or has exemption/clarification - if (!labels.includes(LABELS.COMMUNITY_REVIEW) || hasExemptionOrClarification) { - continue; - } - - const lastUpdated = new Date(pr.updatedAt); - const daysSinceUpdate = (Date.now() - lastUpdated) / MS_PER_DAY; - - // Skip if PR update is within the days threshold - if (daysSinceUpdate <= DAYS_THRESHOLD) { - continue; - } - - console.log(`Processing PR #${pr.number} for ${PRIORITIES.R5} priority consideration`); - - try { - // Get all projects the PR added to - const result = await fetchProjectItem({ - github, - contentId: pr.id - }); - - // Filter specific project - const projectItem = result.node.projectItems.nodes - .find(item => item.project.id === PROJECT_CONFIG.projectId); - - // Skip if PR is already in project - if (projectItem) { - console.log(`PR #${pr.number} is already in project. Skipping.`); - continue; - } - - // Add new PR to project with R5 priority - console.log(`Adding PR #${pr.number} to project with ${PRIORITIES.R5} priority`); - - const addResult = await addItemToProject({ - github, - projectId: PROJECT_CONFIG.projectId, - contentId: pr.id, - }); - - // Set initial priority and status - await Promise.all([ - updateProjectField({ - github, - projectId: PROJECT_CONFIG.projectId, - itemId: addResult.addProjectV2ItemById.item.id, - fieldId: PROJECT_CONFIG.priorityFieldId, - value: r5OptionId, - }), - updateProjectField({ - github, - projectId: PROJECT_CONFIG.projectId, - itemId: addResult.addProjectV2ItemById.item.id, - fieldId: PROJECT_CONFIG.statusFieldId, - value: readyStatusId, - }) - ]); - } catch (error) { - console.error(`Error processing PR #${pr.number}:`, error); - continue; - } -} -} diff --git a/scripts/prioritization/project-api.js b/scripts/prioritization/project-api.js deleted file mode 100644 index 7b1d1ce006b7d..0000000000000 --- a/scripts/prioritization/project-api.js +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Updates a field value for an item in a GitHub Project. - * @param {Object} params - The parameters for updating the project field - * @param {Object} params.github - The GitHub API client - * @param {string} params.projectId - The ID of the project - * @param {string} params.itemId - The ID of the item to update - * @param {string} params.fieldId - The ID of the field to update - * @param {string} params.value - The new value for the field - * @returns {Promise} The GraphQL mutation response - */ -const updateProjectField = async ({ - github, - projectId, - itemId, - fieldId, - value, - }) => { - return github.graphql( - ` - mutation($input: UpdateProjectV2ItemFieldValueInput!) { - updateProjectV2ItemFieldValue(input: $input) { - projectV2Item { - id - } - } - } - `, - { - input: { - projectId, - itemId, - fieldId, - value: value ? { singleSelectOptionId: value } : null, - }, - } - ); - }; - -/** - * Adds an item (PR) to a GitHub Project. - * @param {Object} params - The parameters for adding an item to the project - * @param {Object} params.github - The GitHub API client - * @param {string} params.projectId - The ID of the project - * @param {string} params.contentId - The node ID of the PR to add - * @returns {Promise} The GraphQL mutation response with the new item's ID - */ - const addItemToProject = async ({ github, projectId, contentId }) => { - return github.graphql( - ` - mutation($input: AddProjectV2ItemByIdInput!) { - addProjectV2ItemById(input: $input) { - item { - id - } - } - } - `, - { - input: { - projectId, - contentId, - }, - } - ); - }; - -/** - * Fetches fields configuration for a GitHub Project. - * @param {Object} params - The parameters for fetching project fields - * @param {Object} params.github - The GitHub API client - * @param {string} params.org - The organization name - * @param {number} params.number - The project number - * @returns {Promise} The project fields data including field IDs and options - */ - const fetchProjectFields = async ({ github, org, number }) => { - return github.graphql( - ` - query($org: String!, $number: Int!) { - organization(login: $org) { - projectV2(number: $number) { - fields(first: 20) { - nodes { - ... on ProjectV2SingleSelectField { - id - name - options { - id - name - } - } - } - } - } - } - } - `, - { org, number } - ); - }; - - -/** - * Fetches open pull requests from a repository with pagination support. - * Includes data needed for both R2 and R5 priority processing. - * @param {Object} params - The parameters for fetching pull requests - * @param {Object} params.github - The GitHub API client - * @param {string} params.owner - The repository owner - * @param {string} params.repo - The repository name - * @param {string} [params.cursor] - The pagination cursor - * @returns {Promise} The GraphQL mutation response - */ - const fetchOpenPullRequests = async ({ github, owner, repo, cursor }) => { - return github.graphql( - ` - query($owner: String!, $repo: String!, $cursor: String) { - repository(owner: $owner, name: $repo) { - pullRequests(first: 100, after: $cursor, states: OPEN) { - nodes { - id - number - updatedAt - reviews(last: 100) { - nodes { - state - } - } - commits(last: 1) { - nodes { - commit { - statusCheckRollup { - state - } - } - } - } - labels(first: 10) { - nodes { - name - } - } - } - pageInfo { - hasNextPage - endCursor - } - } - } - } - `, - { owner, repo, cursor } - ); - }; - - /** - * Fetches project item details for a specific PR - * @param {Object} params - The parameters for fetching project item - * @param {Object} params.github - The GitHub API client - * @param {string} params.contentId - PR node ID - * @returns {Promise} Project item details if PR is in project - */ - const fetchProjectItem = async ({ github, contentId }) => { - return github.graphql( - ` - query($contentId: ID!) { - node(id: $contentId) { - ... on PullRequest { - projectItems(first: 100) { - nodes { - id - project { - id - } - fieldValues(first: 8) { - nodes { - ... on ProjectV2ItemFieldSingleSelectValue { - name - field { - ... on ProjectV2SingleSelectField { - name - } - } - } - } - } - } - } - } - } - } - `, - { contentId } - ); - }; - - module.exports = { - updateProjectField, - addItemToProject, - fetchProjectFields, - fetchOpenPullRequests, - fetchProjectItem - }; \ No newline at end of file diff --git a/scripts/prioritization/project-config.js b/scripts/prioritization/project-config.js deleted file mode 100644 index de80a31240f77..0000000000000 --- a/scripts/prioritization/project-config.js +++ /dev/null @@ -1,65 +0,0 @@ -const LABELS = { - CORE: 'contribution/core', - MAINTAINER_REVIEW: 'pr/needs-maintainer-review', - COMMUNITY_REVIEW: 'pr/needs-community-review', - CLARIFICATION_REQUESTED: 'pr/reviewer-clarification-requested', - EXEMPTION_REQUESTED: 'pr-linter/exemption-requested' -}; - -const PRIORITIES = { - R1: '🚨 R1', - R2: 'πŸ”₯ R2', - R3: '🎯 R3', - R4: 'πŸ’­ R4', - R5: 'πŸ“† R5' -}; - -const STATUS = { - READY: '⭐ Ready', - IN_PROGRESS: 'πŸ”„ In Progress', - PAUSED: '⏸️ Paused', - ASSIGNED: 'πŸ‘€ Assigned', - DONE: 'βœ… Done' -}; - -// Time threshold for R5 -const DAYS_THRESHOLD = 21; - -const ATTENTION_STATUS = { - STALLED: { - name: '🚨 Stalled', - threshold: 21, - description: 'Critical attention required' - }, - AGING: { - name: '⚠️ Aging', - threshold: 14, - description: 'Requires immediate attention' - }, - EXTENDED: { - name: 'πŸ•’ Extended', - threshold: 7, - description: 'Taking longer than expected' - } -}; - -/** - * Project configuration for GitHub project automation. - * Note: For projectId, priorityFieldId, statusFieldId, and attentionFieldId, - * refer to Setup section in README.md on how to retrieve these values using GraphQL query. - * These IDs need to be updated only when project fields are modified. - */ -module.exports = { - org: 'aws', - repo: 'aws-cdk', - projectNumber: 263, - projectId: 'PVT_kwDOACIPmc4Av_32', - priorityFieldId: 'PVTSSF_lADOACIPmc4Av_32zgmVmPs', - statusFieldId: 'PVTSSF_lADOACIPmc4Av_32zgmVmF8', - attentionFieldId: 'PVTSSF_lADOACIPmc4Av_32zgmZDdo', - LABELS, - PRIORITIES, - STATUS, - ATTENTION_STATUS, - DAYS_THRESHOLD -};