From 954eef5d5e9f51f5cc871ac252e21cae636a36b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fencl?= Date: Tue, 3 Dec 2024 15:59:30 +0100 Subject: [PATCH 1/4] Add GITLAB_COMMENT_DISCUSSION_AUTORESOLVE optional environment --- .changeset/swift-berries-exist.md | 5 +++++ README.md | 15 ++++++++------- src/comment.ts | 3 +++ src/types.ts | 1 + 4 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 .changeset/swift-berries-exist.md diff --git a/.changeset/swift-berries-exist.md b/.changeset/swift-berries-exist.md new file mode 100644 index 00000000..b8bc532b --- /dev/null +++ b/.changeset/swift-berries-exist.md @@ -0,0 +1,5 @@ +--- +'changesets-gitlab': minor +--- + +Add GITLAB_COMMENT_DISCUSSION_AUTORESOLVE optional environment variable to automaticly resolve added discussion with options to resolve discussion by default (value `all`) or resolve only when changeset is present (value `hasChangeset`) diff --git a/README.md b/README.md index 232428a9..f38af1d4 100644 --- a/README.md +++ b/README.md @@ -48,13 +48,14 @@ GLOBAL_AGENT_NO_PROXY # Like above but for no proxied requests GITLAB_HOST # optional, if you're using custom GitLab host, will fallback to `CI_SERVER_URL` if not provided -GITLAB_TOKEN # required, token with accessibility to push, package registries, and merge request APIs. Note the CI_JOB_TOKEN does not have sufficient permissons -GITLAB_TOKEN_TYPE # optional, type of the provided token in GITLAB_TOKEN. defaults to personal access token. Can be `oauth` if you use Gitlab Oauth (personal access) token.. -GITLAB_CI_USER_NAME # optional, username with accessibility to push, used in pairs of the above token (if it was personal access token). If not set read it from the Gitlab API -GITLAB_CI_USER_EMAIL # optional, default `gitlab[bot]@users.noreply.gitlab.com` -GITLAB_COMMENT_TYPE # optional, type of the comment. defaults to `discussion`. can be set to `note` to not create a discussion instead of a thread -GITLAB_ADD_CHANGESET_MESSAGE # optional, default commit message for adding changesets on GitLab Web UI -DEBUG_GITLAB_CREDENTIAL # optional, default `false` +GITLAB_TOKEN # required, token with accessibility to push, package registries, and merge request APIs. Note the CI_JOB_TOKEN does not have sufficient permissions +GITLAB_TOKEN_TYPE # optional, type of the provided token in GITLAB_TOKEN. defaults to personal access token. Can be `oauth` if you use Gitlab Oauth (personal access) token +GITLAB_CI_USER_NAME # optional, username with accessibility to push, used in pairs of the above token (if it was personal access token). If not set read it from the Gitlab API +GITLAB_CI_USER_EMAIL # optional, default `gitlab[bot]@users.noreply.gitlab.com` +GITLAB_COMMENT_TYPE # optional, type of the comment. defaults to `discussion`. can be set to `note` to not create a discussion instead of a thread +GITLAB_ADD_CHANGESET_MESSAGE # optional, default commit message for adding changesets on GitLab Web UI +GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE # optional, automatically resolve added discussion with options to resolve discussion by default (value `all`) or resolve only when changeset is present (value `hasChangeset`) +DEBUG_GITLAB_CREDENTIAL # optional, default `false` ``` ### Example workflow diff --git a/src/comment.ts b/src/comment.ts index 0a8ae740..c79b9dbe 100644 --- a/src/comment.ts +++ b/src/comment.ts @@ -250,6 +250,8 @@ export const comment = async () => { CI_MERGE_REQUEST_SOURCE_BRANCH_SHA, CI_MERGE_REQUEST_TITLE, GITLAB_COMMENT_TYPE, + GITLAB_COMMENT_DISCUSSION_AUTORESOLVE, + GITLAB_COMMENT_DISCUSSION_AUTORESOLVE_ONLY_CHANGESET_EXISTS, GITLAB_ADD_CHANGESET_MESSAGE, } = env @@ -319,6 +321,7 @@ export const comment = async () => { noteInfo.noteId, { body: prComment, + resolved: GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'always' || (GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'hasChangeset' && hasChangeset), }, ) } diff --git a/src/types.ts b/src/types.ts index de4ce500..08542c84 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,6 +20,7 @@ export type Env = GitLabCIPredefinedVariables & GITLAB_CI_USER_NAME?: string GITLAB_CI_USER_EMAIL: string GITLAB_COMMENT_TYPE: LooseString<'discussion' | 'note'> + GITLAB_COMMENT_DISCUSSION_AUTORESOLVE: LooseString<'always' | 'hasChangeset'> GITLAB_ADD_CHANGESET_MESSAGE?: string DEBUG_GITLAB_CREDENTIAL: LooseString<'1' | 'true'> From db8a74497091d3adb3c52600ae3d3ca3f2cb632b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fencl?= Date: Tue, 3 Dec 2024 21:33:37 +0100 Subject: [PATCH 2/4] Use MergeRequestDiscussions.resolve --- src/comment.ts | 15 +++++++++++++-- src/types.ts | 4 +++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/comment.ts b/src/comment.ts index c79b9dbe..c3a24716 100644 --- a/src/comment.ts +++ b/src/comment.ts @@ -251,7 +251,6 @@ export const comment = async () => { CI_MERGE_REQUEST_TITLE, GITLAB_COMMENT_TYPE, GITLAB_COMMENT_DISCUSSION_AUTORESOLVE, - GITLAB_COMMENT_DISCUSSION_AUTORESOLVE_ONLY_CHANGESET_EXISTS, GITLAB_ADD_CHANGESET_MESSAGE, } = env @@ -314,6 +313,19 @@ export const comment = async () => { switch (GITLAB_COMMENT_TYPE) { case 'discussion': { if (noteInfo) { + if ( + GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'always' || + (GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'hasChangeset' && + hasChangeset) + ) { + await api.MergeRequestDiscussions.resolve( + context.projectId, + mrIid, + noteInfo.discussionId, + true, + ) + } + return api.MergeRequestDiscussions.editNote( context.projectId, mrIid, @@ -321,7 +333,6 @@ export const comment = async () => { noteInfo.noteId, { body: prComment, - resolved: GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'always' || (GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'hasChangeset' && hasChangeset), }, ) } diff --git a/src/types.ts b/src/types.ts index 08542c84..f66b5aae 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,7 +20,9 @@ export type Env = GitLabCIPredefinedVariables & GITLAB_CI_USER_NAME?: string GITLAB_CI_USER_EMAIL: string GITLAB_COMMENT_TYPE: LooseString<'discussion' | 'note'> - GITLAB_COMMENT_DISCUSSION_AUTORESOLVE: LooseString<'always' | 'hasChangeset'> + GITLAB_COMMENT_DISCUSSION_AUTORESOLVE: LooseString< + 'always' | 'hasChangeset' + > GITLAB_ADD_CHANGESET_MESSAGE?: string DEBUG_GITLAB_CREDENTIAL: LooseString<'1' | 'true'> From ca05443efaaf2e9bdf5190caa76f08eaf8b47e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Fencl?= Date: Tue, 3 Dec 2024 21:34:57 +0100 Subject: [PATCH 3/4] Fix value in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f38af1d4..3bc5cc12 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ GITLAB_CI_USER_NAME # optional, username with accessibility t GITLAB_CI_USER_EMAIL # optional, default `gitlab[bot]@users.noreply.gitlab.com` GITLAB_COMMENT_TYPE # optional, type of the comment. defaults to `discussion`. can be set to `note` to not create a discussion instead of a thread GITLAB_ADD_CHANGESET_MESSAGE # optional, default commit message for adding changesets on GitLab Web UI -GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE # optional, automatically resolve added discussion with options to resolve discussion by default (value `all`) or resolve only when changeset is present (value `hasChangeset`) +GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE # optional, automatically resolve added discussion with options to resolve discussion by default (value `always`) or resolve only when changeset is present (value `hasChangeset`) DEBUG_GITLAB_CREDENTIAL # optional, default `false` ``` From e5b811936bcb815f254b7dfc11281b235bb599ac Mon Sep 17 00:00:00 2001 From: JounQin Date: Tue, 1 Apr 2025 14:56:26 +0800 Subject: [PATCH 4/4] refactor: auto resolve discussion comment when changeset presented by default --- .changeset/swift-berries-exist.md | 4 ++-- README.md | 4 ++-- src/comment.ts | 31 +++++++++++++------------------ src/env.ts | 1 - src/main.ts | 24 +++++++++++------------- src/types.ts | 6 ++---- src/utils.ts | 2 ++ 7 files changed, 32 insertions(+), 40 deletions(-) diff --git a/.changeset/swift-berries-exist.md b/.changeset/swift-berries-exist.md index b8bc532b..eb51b1da 100644 --- a/.changeset/swift-berries-exist.md +++ b/.changeset/swift-berries-exist.md @@ -1,5 +1,5 @@ --- -'changesets-gitlab': minor +"changesets-gitlab": minor --- -Add GITLAB_COMMENT_DISCUSSION_AUTORESOLVE optional environment variable to automaticly resolve added discussion with options to resolve discussion by default (value `all`) or resolve only when changeset is present (value `hasChangeset`) +feat: add a new optional `GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE` environment variable to automatically resolve added discussion when changeset is present, if you want to always resolve the discussion, you should actually use `GITLAB_COMMENT_TYPE=note` instead, default `true` diff --git a/README.md b/README.md index 3bc5cc12..46555b5c 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,9 @@ GITLAB_TOKEN_TYPE # optional, type of the provided token in GITLAB_CI_USER_NAME # optional, username with accessibility to push, used in pairs of the above token (if it was personal access token). If not set read it from the Gitlab API GITLAB_CI_USER_EMAIL # optional, default `gitlab[bot]@users.noreply.gitlab.com` GITLAB_COMMENT_TYPE # optional, type of the comment. defaults to `discussion`. can be set to `note` to not create a discussion instead of a thread +GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE # optional, automatically resolve added discussion when changeset is present, if you want to always resolve the discussion, you should actually use `GITLAB_COMMENT_TYPE=note` instead, default `true` GITLAB_ADD_CHANGESET_MESSAGE # optional, default commit message for adding changesets on GitLab Web UI -GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE # optional, automatically resolve added discussion with options to resolve discussion by default (value `always`) or resolve only when changeset is present (value `hasChangeset`) -DEBUG_GITLAB_CREDENTIAL # optional, default `false` +DEBUG_GITLAB_CREDENTIAL # optional, whether to log when setting remote url with sensitive `token` displayed ``` ### Example workflow diff --git a/src/comment.ts b/src/comment.ts index c3a24716..dba3a812 100644 --- a/src/comment.ts +++ b/src/comment.ts @@ -20,7 +20,7 @@ import * as context from './context.js' import { env } from './env.js' import { getChangedPackages } from './get-changed-packages.js' import type { LooseString } from './types.js' -import { getUsername } from './utils.js' +import { getUsername, TRUTHY_VALUES } from './utils.js' const generatedByBotNote = 'Generated By Changesets GitLab Bot' @@ -246,12 +246,8 @@ export const comment = async () => { const { CI_MERGE_REQUEST_IID: mrIid, - CI_MERGE_REQUEST_PROJECT_URL, - CI_MERGE_REQUEST_SOURCE_BRANCH_SHA, - CI_MERGE_REQUEST_TITLE, - GITLAB_COMMENT_TYPE, - GITLAB_COMMENT_DISCUSSION_AUTORESOLVE, - GITLAB_ADD_CHANGESET_MESSAGE, + GITLAB_COMMENT_TYPE: commentType, + GITLAB_ADD_CHANGESET_MESSAGE: commitMessage, } = env if (mrBranch.startsWith('changeset-release')) { @@ -262,7 +258,7 @@ export const comment = async () => { let errFromFetchingChangedFiles = '' try { - const latestCommitSha = CI_MERGE_REQUEST_SOURCE_BRANCH_SHA + const latestCommitSha = env.CI_MERGE_REQUEST_SOURCE_BRANCH_SHA const changedFilesPromise = api.MergeRequests.showChanges( context.projectId, mrIid, @@ -270,7 +266,7 @@ export const comment = async () => { const [noteInfo, hasChangeset, { changedPackages, releasePlan }] = await Promise.all([ - getNoteInfo(api, mrIid, GITLAB_COMMENT_TYPE), + getNoteInfo(api, mrIid, commentType), hasChangesetBeenAdded(changedFilesPromise), getChangedPackages({ changedFiles: changedFilesPromise.then(x => @@ -290,17 +286,17 @@ export const comment = async () => { }), ] as const) - const addChangesetUrl = `${CI_MERGE_REQUEST_PROJECT_URL}/-/new/${mrBranch}?file_name=.changeset/${humanId( + const addChangesetUrl = `${env.CI_MERGE_REQUEST_PROJECT_URL}/-/new/${mrBranch}?file_name=.changeset/${humanId( { separator: '-', capitalize: false, }, )}.md&file=${getNewChangesetTemplate( changedPackages, - CI_MERGE_REQUEST_TITLE, + env.CI_MERGE_REQUEST_TITLE, )}${ - GITLAB_ADD_CHANGESET_MESSAGE - ? '&commit_message=' + encodeURIComponent(GITLAB_ADD_CHANGESET_MESSAGE) + commitMessage + ? '&commit_message=' + encodeURIComponent(commitMessage) : '' }` @@ -310,13 +306,12 @@ export const comment = async () => { : getAbsentMessage(latestCommitSha, addChangesetUrl, releasePlan)) + errFromFetchingChangedFiles - switch (GITLAB_COMMENT_TYPE) { + switch (commentType) { case 'discussion': { if (noteInfo) { if ( - GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'always' || - (GITLAB_COMMENT_DISCUSSION_AUTORESOLVE === 'hasChangeset' && - hasChangeset) + hasChangeset && + TRUTHY_VALUES.has(env.GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE || '1') ) { await api.MergeRequestDiscussions.resolve( context.projectId, @@ -357,7 +352,7 @@ export const comment = async () => { } default: { throw new Error( - `Invalid comment type "${GITLAB_COMMENT_TYPE}", should be "discussion" or "note"`, + `Invalid comment type "${commentType}", should be "discussion" or "note"`, ) } } diff --git a/src/env.ts b/src/env.ts index 5909d10c..c0fc24fe 100644 --- a/src/env.ts +++ b/src/env.ts @@ -18,7 +18,6 @@ export const env = { GITLAB_CI_USER_EMAIL: process.env.GITLAB_CI_USER_EMAIL || 'gitlab[bot]@users.noreply.gitlab.com', GITLAB_COMMENT_TYPE: process.env.GITLAB_COMMENT_TYPE ?? 'discussion', - DEBUG_GITLAB_CREDENTIAL: process.env.DEBUG_GITLAB_CREDENTIAL ?? 'false', // only check for the token if we are explicitly using it diff --git a/src/main.ts b/src/main.ts index eea6878c..bd666c25 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,29 +10,27 @@ import { setupUser } from './git-utils.js' import readChangesetState from './read-changeset-state.js' import { runPublish, runVersion } from './run.js' import type { MainCommandOptions } from './types.js' -import { execSync, getOptionalInput, getUsername } from './utils.js' +import { + execSync, + getOptionalInput, + getUsername, + TRUTHY_VALUES, +} from './utils.js' export const main = async ({ published, onlyChangesets, }: MainCommandOptions = {}) => { - const { - CI, - GITLAB_HOST, - GITLAB_TOKEN, - HOME, - NPM_TOKEN, - DEBUG_GITLAB_CREDENTIAL = 'false', - } = env + const { GITLAB_TOKEN, NPM_TOKEN } = env setOutput('published', false) setOutput('publishedPackages', []) - if (CI) { + if (env.CI) { console.log('setting git user') await setupUser() - const url = new URL(GITLAB_HOST) + const url = new URL(env.GITLAB_HOST) console.log('setting GitLab credentials') const username = await getUsername(createApi()) @@ -47,7 +45,7 @@ export const main = async ({ url.host }${url.pathname.replace(/\/$/, '')}/${env.CI_PROJECT_PATH}.git`, ], - { silent: !['true', '1'].includes(DEBUG_GITLAB_CREDENTIAL) }, + { silent: !TRUTHY_VALUES.has(env.DEBUG_GITLAB_CREDENTIAL!) }, ) } @@ -67,7 +65,7 @@ export const main = async ({ 'No changesets found, attempting to publish any unpublished packages to npm', ) - const npmrcPath = `${HOME}/.npmrc` + const npmrcPath = `${env.HOME}/.npmrc` if (fs.existsSync(npmrcPath)) { console.log('Found existing .npmrc file') } else if (NPM_TOKEN) { diff --git a/src/types.ts b/src/types.ts index f66b5aae..4edbf94f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -20,11 +20,9 @@ export type Env = GitLabCIPredefinedVariables & GITLAB_CI_USER_NAME?: string GITLAB_CI_USER_EMAIL: string GITLAB_COMMENT_TYPE: LooseString<'discussion' | 'note'> - GITLAB_COMMENT_DISCUSSION_AUTORESOLVE: LooseString< - 'always' | 'hasChangeset' - > + GITLAB_COMMENT_DISCUSSION_AUTO_RESOLVE?: LooseString<'1' | 'true'> GITLAB_ADD_CHANGESET_MESSAGE?: string - DEBUG_GITLAB_CREDENTIAL: LooseString<'1' | 'true'> + DEBUG_GITLAB_CREDENTIAL?: LooseString<'1' | 'true'> HOME: string NPM_TOKEN?: string diff --git a/src/utils.ts b/src/utils.ts index 63d37c1d..c209fcc3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -171,3 +171,5 @@ export const getUsername = (api: Gitlab) => { export const cjsRequire = typeof require === 'undefined' ? createRequire(import.meta.url) : require + +export const TRUTHY_VALUES = new Set(['true', '1'])