From c6ec8d17a4eca28a60e976771cd2c8b4dd09dddc Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Fri, 7 Nov 2025 15:15:16 -0600 Subject: [PATCH 1/5] chore: empty commit to sync branch From 2a9db9a3181e43475e19f3b25497a588f9c21b9c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 7 Nov 2025 21:22:20 +0000 Subject: [PATCH 2/5] feat: validate that at least one check is enabled Add validation to ensure at least one of 'check-commits' or 'check-pull-request' is enabled. If both are set to false, the action will fail with a clear error message. Changes: - Add validation check in src/index.js (lines 42-48) - Add 4 comprehensive test cases in __tests__/index.test.js - All 55 JavaScript tests + 29 bash tests passing Co-authored-by: joshjohanning <19912012+joshjohanning@users.noreply.github.com> --- __tests__/index.test.js | 78 +++++++++++++++++++++++++++++++++++++++++ src/index.js | 8 +++++ 2 files changed, 86 insertions(+) diff --git a/__tests__/index.test.js b/__tests__/index.test.js index c6f7f94..2a3e2ef 100644 --- a/__tests__/index.test.js +++ b/__tests__/index.test.js @@ -128,6 +128,84 @@ describe('Azure DevOps Commit Validator', () => { // Restore context mockContext.payload.pull_request = originalPR; }); + + it('should fail if both check-commits and check-pull-request are false', async () => { + mockGetInput.mockImplementation(name => { + if (name === 'check-commits') return 'false'; + if (name === 'check-pull-request') return 'false'; + if (name === 'github-token') return 'github-token'; + return 'false'; + }); + + await run(); + + expect(mockSetFailed).toHaveBeenCalledWith( + "At least one of 'check-commits' or 'check-pull-request' must be set to true. Both are currently set to false." + ); + }); + + it('should pass when only check-commits is enabled', async () => { + mockGetInput.mockImplementation(name => { + if (name === 'check-commits') return 'true'; + if (name === 'check-pull-request') return 'false'; + if (name === 'github-token') return 'github-token'; + if (name === 'fail-if-missing-workitem-commit-link') return 'false'; + return 'false'; + }); + + mockOctokit.rest.pulls.listCommits.mockResolvedValue({ + data: [] + }); + + await run(); + + expect(mockSetFailed).not.toHaveBeenCalled(); + }); + + it('should pass when only check-pull-request is enabled', async () => { + mockGetInput.mockImplementation(name => { + if (name === 'check-commits') return 'false'; + if (name === 'check-pull-request') return 'true'; + if (name === 'github-token') return 'github-token'; + return 'false'; + }); + + mockOctokit.rest.pulls.get.mockResolvedValue({ + data: { + title: 'Test PR AB#123', + body: 'Test body' + } + }); + + await run(); + + expect(mockSetFailed).not.toHaveBeenCalled(); + }); + + it('should pass when both checks are enabled', async () => { + mockGetInput.mockImplementation(name => { + if (name === 'check-commits') return 'true'; + if (name === 'check-pull-request') return 'true'; + if (name === 'github-token') return 'github-token'; + if (name === 'fail-if-missing-workitem-commit-link') return 'false'; + return 'false'; + }); + + mockOctokit.rest.pulls.listCommits.mockResolvedValue({ + data: [] + }); + + mockOctokit.rest.pulls.get.mockResolvedValue({ + data: { + title: 'Test PR AB#123', + body: 'Test body' + } + }); + + await run(); + + expect(mockSetFailed).not.toHaveBeenCalled(); + }); }); describe('Commit validation', () => { diff --git a/src/index.js b/src/index.js index fa41214..fd7587a 100644 --- a/src/index.js +++ b/src/index.js @@ -39,6 +39,14 @@ export async function run() { const commentOnFailure = core.getInput('comment-on-failure') === 'true'; const validateWorkItemExistsFlag = core.getInput('validate-work-item-exists') === 'true'; + // Validate that at least one check is enabled + if (!checkPullRequest && !checkCommits) { + core.setFailed( + "At least one of 'check-commits' or 'check-pull-request' must be set to true. Both are currently set to false." + ); + return; + } + // Get context const context = github.context; const pullNumber = context.payload.pull_request?.number; From 1da5cd5111bed6729b5cb8a16f937c6ea9868c80 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 6 Jan 2026 14:45:20 -0600 Subject: [PATCH 3/5] chore: bump version to 3.0.6 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ebbd9ec..27c6181 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "azure-devops-work-item-link-enforcer-and-linker", - "version": "3.0.5", + "version": "3.0.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "azure-devops-work-item-link-enforcer-and-linker", - "version": "3.0.5", + "version": "3.0.6", "license": "MIT", "dependencies": { "@actions/core": "^2.0.1", diff --git a/package.json b/package.json index 549ac1d..a8cd0cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "azure-devops-work-item-link-enforcer-and-linker", - "version": "3.0.5", + "version": "3.0.6", "private": true, "type": "module", "description": "GitHub Action to enforce that each commit in a pull request be linked to an Azure DevOps work item and automatically link the pull request to each work item ", From f91a72b40ab721b99446774782146b51aa364e88 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 6 Jan 2026 14:47:43 -0600 Subject: [PATCH 4/5] fix: improve error message for validation checks --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index a220c4a..a132432 100644 --- a/src/index.js +++ b/src/index.js @@ -42,7 +42,7 @@ export async function run() { // Validate that at least one check is enabled if (!checkPullRequest && !checkCommits) { core.setFailed( - "At least one of 'check-commits' or 'check-pull-request' must be set to true. Both are currently set to false." + `At least one of 'check-commits' or 'check-pull-request' must be set to true. Both are currently set to false.` ); return; } From 693e13fb4a3ede11c3ded69388794d36ee7c3115 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 6 Jan 2026 14:47:46 -0600 Subject: [PATCH 5/5] fix: update coverage percentage in SVG badge --- badges/coverage.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/badges/coverage.svg b/badges/coverage.svg index c0e9f8b..dbfed95 100644 --- a/badges/coverage.svg +++ b/badges/coverage.svg @@ -1 +1 @@ -Coverage: 80.37%Coverage80.37% \ No newline at end of file +Coverage: 80.56%Coverage80.56% \ No newline at end of file