GoogleCloudPlatform / artifact-registry-npm-tools

15 stars 19 forks source link

Yarn 2 support #16

Open alexander-sergeev opened 3 years ago

alexander-sergeev commented 3 years ago

Do you have plans to support .yarnrc.yml files?

Yarn since version 2 doesn't support .npmrc anymore, so you need to provide info in .yarnrc.yml:

npmScopes:
  workspace:
    npmRegistryServer: 'https://region-npm.pkg.dev/project/repo'
    npmAlwaysAuth: true
    npmAuthToken: 'abc'

Currently google-artifactregistry-auth doesn't support this.

yihanzhen commented 3 years ago

Hi @alexander-sergeev thanks for reporting this and providing the snippet of .yarnrc.yml. We are working on adding support for yarn but there's still a lot in the works. Please stay tuned.

FWIW if you are developing stuff in your own environment (i.e. not as a CI/CD pipeline) you can manually substitute the npmAuthToken part with tokens from gcloud auth print-access-token and it should allow you to push/pull.

alexander-sergeev commented 3 years ago

Hi, Yeah, we solved it by providing fresh access token to yarn via environment variable.

lberrocal commented 3 years ago

This is a blocker for a current project and we haven't found an ideal solution

Hi, Yeah, we solved it by providing fresh access token to yarn via environment variable.

Would you mind sharing some details on this? Curious on how you achieved this :D

alexander-sergeev commented 3 years ago

@lberrocal You can use env variables in your .yarnrc.yml (https://yarnpkg.com/configuration/yarnrc). Write token to env before calling yarn. Notice that tokens are short-lived. export NPM_TOKEN=$(gcloud auth print-access-token)

AndyClausen commented 2 years ago

Does anyone have an easy way of doing this? I'd hate to require my colleagues to update their token every time they want to install or update private packages, and I can't figure how to do it 😕

AndyClausen commented 2 years ago

I figured out a way to do it nicely. I wrote a plugin for it: https://github.com/AndyClausen/yarn-plugin-gcp-auth/ Enjoy 😄

riaanduplessis commented 2 years ago

Thought I'd share my experience with this as I've been intensively working on a private node package for our software at work and setting up all the areas that needs to be authenticated to install the package.

I had to deal with a few parts that needed to be authenticated and also to make it as simple as possible, mainly:

The yarn plugin for some reason just didn't work at all for me, no matter where I used it and what way I was authenticated using the gcloud CLI.

For publishing in Cloud Build

I resorted to using the normal npm publish command and simply kept a .npmrc file in my project's root directory with the registry details along with the .yarnrc.yml file.

This was because I couldn't make use of the token retrieved by gcloud auth print-access-token as it kept returning a forbidden response when setting it as the npmAuthToken in the .yarnrc.yml file. IAM roles are correctly added to the Cloud Build service account, so not sure why this happens.

So this config is solely used for publishing:

@<scope>:registry=https://<region>-npm.pkg.dev/<project>/<repository>/
//<region>-npm.pkg.dev/<project>/<repository>/:always-auth=true

I then added a prepublishOnly hook to my scripts in package.json that generates a token using the google-artifactregistry-auth package:

"scripts": {
  "artifactregistry-login": "yarn dlx google-artifactregistry-auth",
  "prepublishOnly": "yarn artifactregistry-login"
}

This allows for a single step in the cloudbuild.yaml file:

# ... dependencies / build / test here

# Publish new version to dist channel.
- name: node:lts-alpine
  entrypoint: npm
  args: [ publish, --tag, $_DIST_CHANNEL ]

Local installations

Here the gcloud auth print-access-token token works, so applications making use of the package are simply encouraged to add the following as a script in their package.json and run it before they do installations.

"scripts": {
   "set-registry-token": "yarn config set --home npmAuthToken $(gcloud auth print-access-token --project=<project>)"
}

And in their .yarnrc.yml files:

npmScopes:
 <scope>:
    npmAlwaysAuth: true
    npmRegistryServer: "https://<region>-npm.pkg.dev/<project>/<repository>/"

GitHub Action Workflow Installations (To be confirmed)

Also after having set the registry details in the project's .yarnrc.yml file.

I'll come back and edit this once I've confirmed this as I'm in the process of testing it, but thus far I've set up Workload Identity Federation between GitHub and Google Cloud.

My thinking is that the access token generated by the google-github-actions/auth action can then be used to authenticate to Artifact Registry, otherwise I'll probably look to add another step and make use of the gcloud action to generate a token.

This is the workflow steps (still need to confirm if viable):

  # Configure Workload Identity Federation which will create an access token
  # to be used in the subsequent steps.
  - name: Authenticate to Google Cloud
    id: auth
    uses: 'google-github-actions/auth@v0'
    with:
      project_id: <project-id>
      token_format: access_token
      workload_identity_provider: projects/<project-number>/locations/global/workloadIdentityPools/<pool>/providers/<provider>
      service_account: <account>@<project>.iam.gserviceaccount.com

  # The registry is set in the project's `.yarnrc.yml` file so
  # here we only set the authorisation token created in the `auth` step through the
  # YARN_NPM_AUTH_TOKEN environment variable.
  - name: Install private package
    env:
      YARN_NPM_AUTH_TOKEN: ${{ steps.auth.outputs.access_token }}

EDIT:

I can confirm the above example works by setting the YARN_NPM_AUTH_TOKEN environment variable to the created access_token from the google-github-actions/auth action step.

I think using the YARN_NPM_AUTH_TOKEN variable might be the easiest method to standardise across environments.

KubaJastrz commented 1 year ago

This command works for me:

yarn config set --home npmAuthToken $(gcloud auth print-access-token)

I use it instead of

npx google-artifactregistry-auth
kiransmith commented 1 month ago

Taking inspiration from the above answer - in the case of where you are using multiple npmScopes (as I am), then the below scales slightly better.

yarn config set --home --json 'npmScopes.<scopeName>.npmAuthToken' "\"$(gcloud auth print-access-token)\""