Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions .github/workflows/conventional-commit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
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: Checkout
uses: actions/checkout@v6

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*

- name: Install commitlint
run: npm install --no-save @commitlint/cli@20 @commitlint/config-conventional@20

- name: Lint PR title
id: commitlint
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
set -o pipefail
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()
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's already a comment and the workflow runs again, the comment will be left outdated. @copilot what would be a good strategy to handle this outdated comment?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a "Delete outdated comment on success" step that runs when the lint step passes. It finds and deletes any existing bot failure comment, so the PR isn't left with a stale warning after the title is corrected. See 6b75065.

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.**`,
``,
`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\``,
``,
`<details>`,
`<summary>commitlint output</summary>`,
``,
"```",
output,
"```",
`</details>`,
].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,
});
}
Loading