Making of: Dependency Track Upload GitHub Action
Automating the SBOM-Uploads from our pipelines - How we accidentally built a simple GitHub Action in JavaScript
In the Lab we like to experiment with technologies and methods, but do not want to share everything with the world. So sooner or later we wished to have our own npm-registry, so that we can ‘inner-source publish’ components and libraries and tinker with the full CI/CD-workflow of the release process.
So we looked around and found some free offerings:
And as we have our Lab-Kubernetes-Cluster running, we decided to self-host ’nexus repository’ for now.
Sonatype is providing helm-charts for their nexus repository oss , so we want to use these.
# add helm repo
helm repo add sonatype https://sonatype.github.io/helm3-charts/
# install with your values.yaml, see below
helm upgrade --install nexus-rm sonatype/nexus-repository-manager -n nexus-rm --create-namespace --values values.yaml
If you need to uninstall, you can simply use helm uninstall nexus-rm -n nexus-rm
.
We use GitOps with ArgoCD for deployment of the helm-chart to our Lab-Cluster, but that is a different story. For now we just want to look at the manual helm deployment and the post-installation steps.
You might want to customize some details on the first installation:
cpu: 2
and memory: 4Gi
as requests and doubled the values for the limits8 Gi
- this is for the ‘default’, you can also configure any S3-blobstore for your repos laterExample values.yaml for the ingress:
ingress:
enabled: true
ingressClassName: nginx
annotations:
...
<ingress specific annotations for TLS and letsencrypt>
...
cert-manager.io/cluster-issuer: letsencrypt-prod
hostPath: /
hostRepo: repo.<your host>
tls:
- secretName: <your secret name>
hosts:
- repo.<your host>
Now you can install the repository manager - after some reconciliation, the repo is hopefully available under
your specified URL https://repo.<your host>
.
The initial password for the admin user is written to /nexus-data/admin.password
in the container,
so get some shell to the container and obtain the password.
After that you will be able to log in to the Nexus Repository Manager’s Web-Interface.
You might want to go to ‘Security / Anonymous Access’ and uncheck ‘Allow anonymous users to access the server’ if you want to keep your packages private.
To enable npm-authentication, you have to activate ’npm Bearer Token Realm’ in ‘Security / Realms’.
Otherwise you’ll see Unable to authenticate, need: BASIC realm="Sonatype Nexus Repository Manager"
.
Let’s name our repositories ’npm-lab-hosted’ (for packages stored in your nexus), ’npm-lab-proxy’ (proxy for registry.npmjs.org) and group them by ’npm-lab-group’.
npm install
If we want to use our published packages, we need credentials for accessing our package-repository.
We create a role ’npm-read’ and assign the following privilege: `nx-repository-view-npm-npm-lab-group-read``
Create a user ’npm-read’ that has role ’npm-read’.
Now encode the credentials using echo -n 'myuser:mypassword' | openssl base64
and construct your .npmrc
-file:
registry = https://repo.<your host>/repository/npm-lab-group/
email=<your email>
always-auth=true
_auth=<myuser:mypassword base64-encoded>
Copy the .npmrc to the root of your npm-project. If everything is right, you should now
be able to npm install <any package>
from either your hosted-repo (your own published packages)
or the proxy-repo (packages published in registry.npmjs.org).
npm publish
in your CI/CD pipelineTo publish packages to our repository from our CI/CD-pipelines, we need credentials with appropriate “write”-permissions for our npm-repo.
We create another role ’npm-publish’ and assign the following privileges:
This gives the user API-access to the hosted repo.
Then create a user ’npm-publish’ that has role ’npm-publish'.
Now encode the credentials using echo -n 'npm-publish:<mypassword>' | openssl base64
and construct your .npmrc
-file:
registry = https://repo.<your host>/repository/npm-lab-hosted/
email=<your email>
always-auth=true
_auth=<myuser:mypassword base64-encoded>
Use the .npmrc file as secret in your CI/CD-pipeline. If everything works as expected,
you should now be able to npm publish --repository https://repo.<your host>/repository/npm-lab-hosted/
(as workaround
)
to your hosted-repo (your own published packages).
…
As you are experimenting with users, npmrc and so on, please be aware, that the credentials you have useed
with npm login
previously are stored in your npm user-config, see npm config edit
.
So if you keep getting Unable to authenticate
like below, please try to delete the saved credentials:
npm ERR! code E401
npm ERR! Unable to authenticate, need: BASIC realm="Sonatype Nexus Repository Manager"
You just have to setup a local npm-repository with npm init
, write some code and test… then finally:
npm version v0.0.1
git push
npm publish
to upload the package to our registryWe can easily automate the last step using a CI/CD-pipeline, e.g as Github Action , that runs on the release of a tagged version:
name: Publish to NPM
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: materialize .npmrc
env:
NPMRC: ${{secrets.NPMRC}}
run: |
echo $NPMRC | base64 -d > .npmrc
shell: bash
- name: Publish package on NPM 📦
run: |
npm publish --registry https://repo.<your host>/repository/npm-lab-hosted/
The Action, that runs on release of a tagged version, materializes the base64-encoded .npmrc
from the ‘NPMRC’-Secret
(with credentials for user npm-publish
, see above) and uses the credentials to publish the package
to your private hosted repository.
Nexus Repository Manager is easy to install and with a little setup, you are able to use it as private npm-registry and integrate it in your CI/CD-Workflows. But there is more - we can also use it for helm-, go- and python-packages if we like.
Automating the SBOM-Uploads from our pipelines - How we accidentally built a simple GitHub Action in JavaScript
Unleash the power of Dependency Track: safeguarding your software with continuous SBOM analysis