Loading .gitignore +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ _testmain.go vendor .go/ .golangci-lint/ scripts/commitlint/node_modules # reports gl-code-quality-report.json Loading .gitlab-ci.yml +8 −5 Original line number Diff line number Diff line Loading @@ -138,12 +138,15 @@ commitlint: stage: lint needs: [] rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' image: name: commitlint/commitlint:19.9.1 entrypoint: [""] # lint.js script makes an API call without authentication, so the project or fork must be public - if: '$CI_MERGE_REQUEST_IID && $CI_PROJECT_VISIBILITY == "public"' when: always image: ${GITLAB_DEPENDENCY_PROXY}node:22-slim script: - commitlint --from ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --to ${CI_COMMIT_SHA} - apt-get update && apt-get install -y git - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME $CI_COMMIT_SHA - cd scripts/commitlint && npm ci - ./lint.sh tests:unit: extends: Loading .tool-versions +1 −0 Original line number Diff line number Diff line Loading @@ -2,3 +2,4 @@ golang 1.23 golangci-lint 2.3.1 gofumpt 0.8.0 buf 1.55.1 node 24.8.0 No newline at end of file commitlint.config.mjsdeleted 100644 → 0 +0 −8 Original line number Diff line number Diff line export default { extends: ['@commitlint/config-conventional'], "rules": { "body-max-line-length": [0, "always", 100], "subject-case": [0, "always", ["sentence-case"]], "header-max-length": [2, "always", 200] } }; scripts/commitlint/lint.js 0 → 100644 +103 −0 Original line number Diff line number Diff line import read from '@commitlint/read'; import lint from '@commitlint/lint'; import format from '@commitlint/format'; import config from '@commitlint/config-conventional'; // You can test the script by setting these environment variables const { CI_MERGE_REQUEST_DIFF_BASE_SHA, // refers to the main branch CI_MERGE_REQUEST_SQUASH_ON_MERGE, // true if the squash MR checkbox is ticked CI_MERGE_REQUEST_TITLE, // MR Title CI_MERGE_REQUEST_EVENT_TYPE, // equal to 'merge_train' if the pipeline is a merge train pipeline CI, // true when script is run in a CI/CD pipeline LAST_MR_COMMIT, // This variable is created by `lint.sh` script. It represents the MR commit that's direct parent of the newly created merge commit. } = process.env; // Leaving this alone for now even though it doesn't point to client-go because // we'll want to create our own commit documentation eventually. I don't think we need to // for the first iteration though. const urlSemanticRelease = 'https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/docs/developer/commits.md'; // See rule docs https://commitlint.js.org/#/reference-rules const customRules = { "body-max-line-length": [0, "always", 100], "subject-case": [0, "always", ["sentence-case"]], "header-max-length": [2, "always", 200], // Inherited from upstream cli configuration, but // I think they're worth leaving for client-go. "body-leading-blank": [2, "always"], "footer-leading-blank": [2, "always"] }; async function getCommitsInMr() { const diffBaseSha = CI_MERGE_REQUEST_DIFF_BASE_SHA; const sourceBranchSha = LAST_MR_COMMIT; const messages = await read({ from: diffBaseSha, to: sourceBranchSha }); return messages; } const messageMatcher = r => r.test.bind(r); async function isConventional(message) { return lint( message, { ...config.rules, ...customRules }, { defaultIgnores: false, ignores: [ messageMatcher(/^[Rr]evert .*/), messageMatcher(/^(?:fixup|squash)!/), messageMatcher(/^Merge branch/), messageMatcher(/^\d+\.\d+\.\d+/), ], }, ); } async function lintMr() { const commits = await getCommitsInMr(); // When MR is set to squash, but it's not yet being merged, we check the MR Title if ( CI_MERGE_REQUEST_SQUASH_ON_MERGE === 'true' && CI_MERGE_REQUEST_EVENT_TYPE !== 'merge_train' ) { console.log( 'INFO: The MR is set to squash. We will lint the MR Title (used as the commit message by default).', ); return isConventional(CI_MERGE_REQUEST_TITLE).then(Array.of); } console.log('INFO: Checking all commits that will be added by this MR.'); return Promise.all(commits.map(commit => isConventional(commit))); } async function run() { if (!CI) { console.error('This script can only run in GitLab CI.'); process.exit(1); } if (!LAST_MR_COMMIT) { console.error( 'LAST_MR_COMMIT environment variable is not present. Make sure this script is run from `lint.sh`', ); process.exit(1); } const results = await lintMr(); console.error(format({ results }, { helpUrl: urlSemanticRelease })); const numOfErrors = results.reduce((acc, result) => acc + result.errors.length, 0); if (numOfErrors !== 0) { process.exit(1); } } run().catch(err => { console.error(err); process.exit(1); }); Loading
.gitignore +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ _testmain.go vendor .go/ .golangci-lint/ scripts/commitlint/node_modules # reports gl-code-quality-report.json Loading
.gitlab-ci.yml +8 −5 Original line number Diff line number Diff line Loading @@ -138,12 +138,15 @@ commitlint: stage: lint needs: [] rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' image: name: commitlint/commitlint:19.9.1 entrypoint: [""] # lint.js script makes an API call without authentication, so the project or fork must be public - if: '$CI_MERGE_REQUEST_IID && $CI_PROJECT_VISIBILITY == "public"' when: always image: ${GITLAB_DEPENDENCY_PROXY}node:22-slim script: - commitlint --from ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --to ${CI_COMMIT_SHA} - apt-get update && apt-get install -y git - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME $CI_COMMIT_SHA - cd scripts/commitlint && npm ci - ./lint.sh tests:unit: extends: Loading
.tool-versions +1 −0 Original line number Diff line number Diff line Loading @@ -2,3 +2,4 @@ golang 1.23 golangci-lint 2.3.1 gofumpt 0.8.0 buf 1.55.1 node 24.8.0 No newline at end of file
commitlint.config.mjsdeleted 100644 → 0 +0 −8 Original line number Diff line number Diff line export default { extends: ['@commitlint/config-conventional'], "rules": { "body-max-line-length": [0, "always", 100], "subject-case": [0, "always", ["sentence-case"]], "header-max-length": [2, "always", 200] } };
scripts/commitlint/lint.js 0 → 100644 +103 −0 Original line number Diff line number Diff line import read from '@commitlint/read'; import lint from '@commitlint/lint'; import format from '@commitlint/format'; import config from '@commitlint/config-conventional'; // You can test the script by setting these environment variables const { CI_MERGE_REQUEST_DIFF_BASE_SHA, // refers to the main branch CI_MERGE_REQUEST_SQUASH_ON_MERGE, // true if the squash MR checkbox is ticked CI_MERGE_REQUEST_TITLE, // MR Title CI_MERGE_REQUEST_EVENT_TYPE, // equal to 'merge_train' if the pipeline is a merge train pipeline CI, // true when script is run in a CI/CD pipeline LAST_MR_COMMIT, // This variable is created by `lint.sh` script. It represents the MR commit that's direct parent of the newly created merge commit. } = process.env; // Leaving this alone for now even though it doesn't point to client-go because // we'll want to create our own commit documentation eventually. I don't think we need to // for the first iteration though. const urlSemanticRelease = 'https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/docs/developer/commits.md'; // See rule docs https://commitlint.js.org/#/reference-rules const customRules = { "body-max-line-length": [0, "always", 100], "subject-case": [0, "always", ["sentence-case"]], "header-max-length": [2, "always", 200], // Inherited from upstream cli configuration, but // I think they're worth leaving for client-go. "body-leading-blank": [2, "always"], "footer-leading-blank": [2, "always"] }; async function getCommitsInMr() { const diffBaseSha = CI_MERGE_REQUEST_DIFF_BASE_SHA; const sourceBranchSha = LAST_MR_COMMIT; const messages = await read({ from: diffBaseSha, to: sourceBranchSha }); return messages; } const messageMatcher = r => r.test.bind(r); async function isConventional(message) { return lint( message, { ...config.rules, ...customRules }, { defaultIgnores: false, ignores: [ messageMatcher(/^[Rr]evert .*/), messageMatcher(/^(?:fixup|squash)!/), messageMatcher(/^Merge branch/), messageMatcher(/^\d+\.\d+\.\d+/), ], }, ); } async function lintMr() { const commits = await getCommitsInMr(); // When MR is set to squash, but it's not yet being merged, we check the MR Title if ( CI_MERGE_REQUEST_SQUASH_ON_MERGE === 'true' && CI_MERGE_REQUEST_EVENT_TYPE !== 'merge_train' ) { console.log( 'INFO: The MR is set to squash. We will lint the MR Title (used as the commit message by default).', ); return isConventional(CI_MERGE_REQUEST_TITLE).then(Array.of); } console.log('INFO: Checking all commits that will be added by this MR.'); return Promise.all(commits.map(commit => isConventional(commit))); } async function run() { if (!CI) { console.error('This script can only run in GitLab CI.'); process.exit(1); } if (!LAST_MR_COMMIT) { console.error( 'LAST_MR_COMMIT environment variable is not present. Make sure this script is run from `lint.sh`', ); process.exit(1); } const results = await lintMr(); console.error(format({ results }, { helpUrl: urlSemanticRelease })); const numOfErrors = results.reduce((acc, result) => acc + result.errors.length, 0); if (numOfErrors !== 0) { process.exit(1); } } run().catch(err => { console.error(err); process.exit(1); });