diff --git a/.changeset/dirty-ducks-relax.md b/.changeset/dirty-ducks-relax.md new file mode 100644 index 00000000..77c6a9d4 --- /dev/null +++ b/.changeset/dirty-ducks-relax.md @@ -0,0 +1,5 @@ +--- +'changesets-gitlab': minor +--- + +Add support for `PREFER_PROJECT_LEVEL_NPMRC` variable checking the project root rather than `$HOME` for a `.npmrc` file when validating auth diff --git a/README.md b/README.md index d8b207ff..e8968e8f 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ GITLAB_CI_USER_EMAIL # optional, default `gitlab[bot]@users.noreply.gitl 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` +PREFER_PROJECT_LEVEL_NPMRC # optional, check project root instead of HOME for a .npmrc file when validating auth ``` ### Example workflow @@ -83,44 +84,39 @@ release: #### With Publishing -Before you can setup this action with publishing, you'll need to have an [npm token](https://docs.npmjs.com/creating-and-viewing-authentication-tokens) that can publish the packages in the repo you're setting up the action for and doesn't have 2FA on publish enabled ([2FA on auth can be enabled](https://docs.npmjs.com/about-two-factor-authentication)). You'll also need to [add it as a custom environment variable on your GitLab repo](https://docs.gitlab.com/ee/ci/variables/#custom-cicd-variables) with the name `NPM_TOKEN`. Once you've done that, you can create a file at `.gitlab-ci.yml` with the following content. +To enable publishing of package(s), add a publish command to the `INPUT_PUBLISH` variable in your release step. ```yml -stages: - - comment - - release - -before_script: yarn --frozen-lockfile - -comment: - image: node:lts-alpine - stage: comment - only: merge_requests - script: yarn changesets-gitlab comment - release: image: node:lts-alpine only: main script: yarn changesets-gitlab variables: - INPUT_PUBLISH: yarn release + INPUT_PUBLISH: changeset publish ``` -By default the GitLab CI cli creates a `.npmrc` file with the following content: +There's two ways you can authenticate with the GitLab CI cli. + +- Configure `$HOME/.npmrc` with auth + - Alternatively the project root `.npmrc` by setting `PREFER_PROJECT_LEVEL_NPMRC` to `true` +- Setting `NPM_TOKEN` in [custom CI/CD variables](https://docs.gitlab.com/ee/ci/variables/#custom-cicd-variables) (only works with the public registry `registry.npmjs.org`) + +If you're using the public npm registry, you'll need to have an [npm token](https://docs.npmjs.com/creating-and-viewing-authentication-tokens) that can publish the packages in the repo you're setting up the action for and doesn't have 2FA on publish enabled ([2FA on auth can be enabled](https://docs.npmjs.com/about-two-factor-authentication)). +[Add it as a custom environment variable on your GitLab repo](https://docs.gitlab.com/ee/ci/variables/#custom-cicd-variables) with the name `NPM_TOKEN`. +The GitLab CI cli then creates a `.npmrc` file with the following content: ```sh //registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN} ``` -However, if a `.npmrc` file is found, the GitLab CI cli does not recreate the file. This is useful if you need to configure the `.npmrc` file on your own. +If `.npmrc` exists in `$HOME` (or in the project root with `PREFER_PROJECT_LEVEL_NPMRC` set to `true`), the GitLab CI cli does not touch the file. +This is useful if you need to configure the `.npmrc` file on your own. For example, you can add a step before running the Changesets GitLab CI cli: ```yml -script: | - cat << EOF > "$HOME/.npmrc" - email=my@email.com - //registry.npmjs.org/:_authToken=$NPM_TOKEN - EOF +script: + - echo "//${NPM_REGISTRY}/:_authToken=${NPM_TOKEN}" >> ${HOME}.npmrc + - yarn changesets-gitlab ``` #### With version script diff --git a/src/main.ts b/src/main.ts index 0f2625b4..5d8a3c4e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,6 +13,14 @@ import { execSync, getOptionalInput, getUsername } from './utils.js' import { createApi } from './index.js' +const getNpmrcPath = () => { + if (env.CI && env.PREFER_PROJECT_LEVEL_NPMRC) { + return `${env.CI_PROJECT_DIR}/.npmrc` + } + + return `${env.HOME}/.npmrc` +} + export const main = async ({ published, onlyChangesets, @@ -21,7 +29,6 @@ export const main = async ({ CI, GITLAB_HOST, GITLAB_TOKEN, - HOME, NPM_TOKEN, DEBUG_GITLAB_CREDENTIAL = 'false', } = env @@ -68,7 +75,7 @@ export const main = async ({ 'No changesets found, attempting to publish any unpublished packages to npm', ) - const npmrcPath = `${HOME}/.npmrc` + const npmrcPath = getNpmrcPath() 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 dd3932aa..66c57b9c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -25,6 +25,7 @@ export type Env = GitLabCIPredefinedVariables & HOME: string NPM_TOKEN?: string + PREFER_PROJECT_LEVEL_NPMRC?: string } type MergeRequestVariables = @@ -44,10 +45,12 @@ type GitLabCIPredefinedVariables = { GITLAB_USER_NAME: string } & ( | { // this is used to be checked if the current job is in a CI environment CI: undefined + CI_PROJECT_DIR: undefined } | { CI: 'true' CI_PROJECT_PATH: string CI_SERVER_URL: string + CI_PROJECT_DIR: string } )