From 1a00e48c343d0eb036710a3e36af62a7500c448c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 16:27:06 +0000 Subject: [PATCH 1/7] Initial plan From 3a64bd2a9e44fc6c980b822115a06a999dd5d927 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 16:30:29 +0000 Subject: [PATCH 2/7] feat: add workflow to check conventional commit PR titles Co-authored-by: asasine <5421969+asasine@users.noreply.github.com> Agent-Logs-Url: https://github.com/asasine/spongebob/sessions/452cef64-bbc4-4cf9-bf07-44f9c64726be --- .github/workflows/conventional-commit.yaml | 73 ++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 .github/workflows/conventional-commit.yaml diff --git a/.github/workflows/conventional-commit.yaml b/.github/workflows/conventional-commit.yaml new file mode 100644 index 0000000..7ea4b44 --- /dev/null +++ b/.github/workflows/conventional-commit.yaml @@ -0,0 +1,73 @@ +name: Conventional Commit + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + branches: ["main"] + +jobs: + check-title: + name: Check PR Title + runs-on: ubuntu-latest + + permissions: + pull-requests: write + + steps: + - name: Check conventional commit format + uses: actions/github-script@v7 + with: + script: | + const title = context.payload.pull_request.title; + + // Conventional commit pattern: type(optional scope): description + // Types from conventionalcommits.org commonly used with release-plz + const pattern = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?: .+$/; + + if (pattern.test(title)) { + console.log(`PR title "${title}" follows conventional commit format.`); + return; + } + + const body = [ + `**PR title does not follow [Conventional Commits](https://www.conventionalcommits.org/) format.**`, + ``, + `Please update the PR title to match the format: \`type(optional scope): description\``, + ``, + `Examples:`, + `- \`feat: added new feature\``, + `- \`fix(cli): corrected typo in help message\``, + `- \`docs: updated README.md\``, + ``, + `Supported types: \`feat\`, \`fix\`, \`docs\`, \`style\`, \`refactor\`, \`perf\`, \`test\`, \`build\`, \`ci\`, \`chore\`, \`revert\``, + ].join("\n"); + + // Find existing bot comment to update instead of creating duplicates + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + + const marker = "**PR title does not follow [Conventional Commits]"; + const existing = comments.find( + (c) => c.user.type === "Bot" && c.body.includes(marker) + ); + + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body: body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + body: body, + }); + } + + core.setFailed(`PR title "${title}" does not follow conventional commit format.`); From 6817b9c3f833798cc028696d5a7ebdd5ef0ee0dd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 16:38:47 +0000 Subject: [PATCH 3/7] refactor: use @commitlint/config-conventional instead of custom regex Co-authored-by: asasine <5421969+asasine@users.noreply.github.com> Agent-Logs-Url: https://github.com/asasine/spongebob/sessions/056e8835-9461-45a6-aadc-ff788701b303 --- .github/workflows/conventional-commit.yaml | 42 ++++++++++++++-------- commitlint.config.js | 3 ++ 2 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 commitlint.config.js diff --git a/.github/workflows/conventional-commit.yaml b/.github/workflows/conventional-commit.yaml index 7ea4b44..a3d4172 100644 --- a/.github/workflows/conventional-commit.yaml +++ b/.github/workflows/conventional-commit.yaml @@ -14,20 +14,30 @@ jobs: pull-requests: write steps: - - name: Check conventional commit format - uses: actions/github-script@v7 + - name: Checkout + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v4 with: - script: | - const title = context.payload.pull_request.title; + node-version: lts/* - // Conventional commit pattern: type(optional scope): description - // Types from conventionalcommits.org commonly used with release-plz - const pattern = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?: .+$/; + - name: Install commitlint + run: npm install --no-save @commitlint/cli@20 @commitlint/config-conventional@20 - if (pattern.test(title)) { - console.log(`PR title "${title}" follows conventional commit format.`); - return; - } + - name: Lint PR title + id: commitlint + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: echo "$PR_TITLE" | npx commitlint 2>&1 | tee /tmp/commitlint-output.txt + + - name: Comment on failure + if: failure() + uses: actions/github-script@v7 + with: + script: | + const fs = require("fs"); + const output = fs.readFileSync("/tmp/commitlint-output.txt", "utf8").trim(); const body = [ `**PR title does not follow [Conventional Commits](https://www.conventionalcommits.org/) format.**`, @@ -39,7 +49,13 @@ jobs: `- \`fix(cli): corrected typo in help message\``, `- \`docs: updated README.md\``, ``, - `Supported types: \`feat\`, \`fix\`, \`docs\`, \`style\`, \`refactor\`, \`perf\`, \`test\`, \`build\`, \`ci\`, \`chore\`, \`revert\``, + `
`, + `commitlint output`, + ``, + "```", + output, + "```", + `
`, ].join("\n"); // Find existing bot comment to update instead of creating duplicates @@ -69,5 +85,3 @@ jobs: body: body, }); } - - core.setFailed(`PR title "${title}" does not follow conventional commit format.`); diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000..84dcb12 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ['@commitlint/config-conventional'], +}; From 6ea4091e38fbf21a2a0f22388f5fd023f20f7e99 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 16:39:16 +0000 Subject: [PATCH 4/7] fix: use pipefail so commitlint exit code propagates through tee Co-authored-by: asasine <5421969+asasine@users.noreply.github.com> Agent-Logs-Url: https://github.com/asasine/spongebob/sessions/056e8835-9461-45a6-aadc-ff788701b303 --- .github/workflows/conventional-commit.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/conventional-commit.yaml b/.github/workflows/conventional-commit.yaml index a3d4172..c44e3a8 100644 --- a/.github/workflows/conventional-commit.yaml +++ b/.github/workflows/conventional-commit.yaml @@ -29,7 +29,9 @@ jobs: id: commitlint env: PR_TITLE: ${{ github.event.pull_request.title }} - run: echo "$PR_TITLE" | npx commitlint 2>&1 | tee /tmp/commitlint-output.txt + run: | + set -o pipefail + echo "$PR_TITLE" | npx commitlint 2>&1 | tee /tmp/commitlint-output.txt - name: Comment on failure if: failure() From 417871fd39eea2ed2ca678396a8cc276623041b5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 16:44:04 +0000 Subject: [PATCH 5/7] refactor: remove commitlint.config.js and generate config inline in workflow Co-authored-by: asasine <5421969+asasine@users.noreply.github.com> Agent-Logs-Url: https://github.com/asasine/spongebob/sessions/8d284569-7830-4561-976e-dba930fca6c6 --- .github/workflows/conventional-commit.yaml | 1 + commitlint.config.js | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 commitlint.config.js diff --git a/.github/workflows/conventional-commit.yaml b/.github/workflows/conventional-commit.yaml index c44e3a8..1b065ac 100644 --- a/.github/workflows/conventional-commit.yaml +++ b/.github/workflows/conventional-commit.yaml @@ -31,6 +31,7 @@ jobs: PR_TITLE: ${{ github.event.pull_request.title }} run: | set -o pipefail + echo '{"extends":["@commitlint/config-conventional"]}' > .commitlintrc.json echo "$PR_TITLE" | npx commitlint 2>&1 | tee /tmp/commitlint-output.txt - name: Comment on failure diff --git a/commitlint.config.js b/commitlint.config.js deleted file mode 100644 index 84dcb12..0000000 --- a/commitlint.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: ['@commitlint/config-conventional'], -}; From 8a0a6eadcf201b5106b60328f9e1c7001e6f46fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 16:47:03 +0000 Subject: [PATCH 6/7] fix: disable color in commitlint output to avoid ANSI codes in PR comments Co-authored-by: asasine <5421969+asasine@users.noreply.github.com> Agent-Logs-Url: https://github.com/asasine/spongebob/sessions/6f848dc1-c629-413d-8fb3-61638c53bf62 --- .github/workflows/conventional-commit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conventional-commit.yaml b/.github/workflows/conventional-commit.yaml index 1b065ac..2a1ae87 100644 --- a/.github/workflows/conventional-commit.yaml +++ b/.github/workflows/conventional-commit.yaml @@ -32,7 +32,7 @@ jobs: run: | set -o pipefail echo '{"extends":["@commitlint/config-conventional"]}' > .commitlintrc.json - echo "$PR_TITLE" | npx commitlint 2>&1 | tee /tmp/commitlint-output.txt + echo "$PR_TITLE" | npx commitlint --color false 2>&1 | tee /tmp/commitlint-output.txt - name: Comment on failure if: failure() From 6b7506500a6870adf2703ba57b0dc10c1956277b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 17:19:57 +0000 Subject: [PATCH 7/7] fix: delete outdated failure comment when PR title passes validation Co-authored-by: asasine <5421969+asasine@users.noreply.github.com> Agent-Logs-Url: https://github.com/asasine/spongebob/sessions/c9424335-bc43-4da4-9aed-c6cd5338b1b4 --- .github/workflows/conventional-commit.yaml | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/conventional-commit.yaml b/.github/workflows/conventional-commit.yaml index 2a1ae87..e485bff 100644 --- a/.github/workflows/conventional-commit.yaml +++ b/.github/workflows/conventional-commit.yaml @@ -34,6 +34,30 @@ jobs: echo '{"extends":["@commitlint/config-conventional"]}' > .commitlintrc.json echo "$PR_TITLE" | npx commitlint --color false 2>&1 | tee /tmp/commitlint-output.txt + - name: Delete outdated comment on success + if: success() + uses: actions/github-script@v7 + with: + script: | + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + }); + + const marker = "**PR title does not follow [Conventional Commits]"; + const existing = comments.find( + (c) => c.user.type === "Bot" && c.body.includes(marker) + ); + + if (existing) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + }); + } + - name: Comment on failure if: failure() uses: actions/github-script@v7