NPM Release
The npm-release jobs are used to prepare and create GitLab releases. They download build artifacts, tag Docker images with release versions, and create GitLab releases.
Overview
The npm-release jobs include:
.prepare_job: Prepares the release by downloading artifacts, tagging Docker images, and exporting release variables.release_job: Creates a GitLab release using the release-cli
Variables
The following variables can be configured:
| Variable | Description | Default | Required |
|---|---|---|---|
CONTAINER_REGISTRY_ID | Container registry project ID | 4495833 | No |
DOCKER_BUILD_IMAGE | Docker image for Docker-in-Docker | 'docker:19.03.11' | No |
DOCKER_BUILD_SERVICE | Docker-in-Docker service version | '19.03.11-dind' | No |
NODE_IMAGE | Node.js image (not used in current jobs) | 'node:16.3.0-alpine' | No |
CI_TOKEN | GitLab CI token for API access | '' | Yes |
Variable Details
- CONTAINER_REGISTRY_ID: Container registry project ID (used for registry operations)
- DOCKER_BUILD_IMAGE: Docker image version for Docker-in-Docker service
- DOCKER_BUILD_SERVICE: Docker-in-Docker service version
- NODE_IMAGE: Node.js image (defined but not currently used in the jobs)
- CI_TOKEN: GitLab CI token for downloading artifacts via API
GitLab CI/CD Variables
The jobs use the following built-in GitLab CI/CD variables:
CI_REGISTRY_USER: GitLab registry usernameCI_REGISTRY_PASSWORD: GitLab registry passwordCI_REGISTRY: GitLab container registry URLCI_REGISTRY_IMAGE: The address of the container registry tied to the projectCI_PROJECT_ID: Project IDCI_MERGE_REQUEST_SOURCE_BRANCH_NAME: Source branch name of the merge requestCI_COMMIT_SHA: Commit SHA for the release
Job Types
.prepare_job
Prepares the release by downloading build artifacts, extracting Docker image information, and tagging images with release versions.
Usage
variables:
CONTAINER_REGISTRY_ID: 4495833
DOCKER_BUILD_IMAGE: 'docker:19.03.11'
DOCKER_BUILD_SERVICE: '19.03.11-dind'
CI_TOKEN: ''
.prepare_job:
image: $DOCKER_BUILD_IMAGE
services:
- docker:$DOCKER_BUILD_SERVICE
variables:
REGISTRY_ID: $CONTAINER_REGISTRY_ID
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- apk update
- apk --no-cache add curl
script:
- |
BRANCH_NAME=${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME/\//_}
VERSION=${BRANCH_NAME}
echo VERSION = $VERSION
echo "URL=https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/artifacts/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}/download?job=docker-build_job"
curl --location --output artifacts.zip --header "Private-Token: ${CI_TOKEN}" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/artifacts/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}/download?job=docker-build_job"
unzip -o artifacts.zip
DOCKER_IMAGE=$(cat pipeline.env)
TAG=$(cat pipeline.env| awk -F "_" '{print $2}')
echo "releasing TAG = $TAG"
echo "pulling image: ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE}"
docker pull ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE}
echo "tagging image: ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE} ${CI_REGISTRY_IMAGE}:${TAG}"
docker tag ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE} ${CI_REGISTRY_IMAGE}:${TAG}
echo "pushing image: ${CI_REGISTRY_IMAGE}:${TAG}"
docker push ${CI_REGISTRY_IMAGE}:${TAG}
- echo "EXTRA_DESCRIPTION=RELEASE=v${TAG} | DATE=$(date +%Y-%m-%d)" >> variables.env
- echo "TAG=v${TAG}" >> variables.env
artifacts:
reports:
dotenv: variables.env
Job Details
Before Script:
-
Docker login:
docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY -
Install curl:
apk update
apk --no-cache add curl
Script:
-
Extract version from branch name:
BRANCH_NAME=${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME/\//_}
VERSION=${BRANCH_NAME}- Replaces
/with_in branch name (e.g.,release/1.0.0→release_1.0.0)
- Replaces
-
Download build artifacts:
curl --location --output artifacts.zip \
--header "Private-Token: ${CI_TOKEN}" \
"https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/artifacts/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}/download?job=docker-build_job"
unzip -o artifacts.zip- Downloads artifacts from the
docker-build_jobin the source branch - Extracts the artifacts (should contain
pipeline.env)
- Downloads artifacts from the
-
Extract Docker image information:
DOCKER_IMAGE=$(cat pipeline.env)
TAG=$(cat pipeline.env| awk -F "_" '{print $2}')- Reads Docker image tag from
pipeline.env - Extracts release tag (assumes format:
{prefix}_{tag})
- Reads Docker image tag from
-
Tag and push Docker image:
docker pull ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE}
docker tag ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE} ${CI_REGISTRY_IMAGE}:${TAG}
docker push ${CI_REGISTRY_IMAGE}:${TAG}- Pulls the build image
- Tags it with the release tag
- Pushes the tagged image
-
Generate release variables:
echo "EXTRA_DESCRIPTION=RELEASE=v${TAG} | DATE=$(date +%Y-%m-%d)" >> variables.env
echo "TAG=v${TAG}" >> variables.env
Artifacts:
Exports variables via dotenv artifact for use in subsequent jobs.
.release_job
Creates a GitLab release using the release-cli.
Usage
.release_job:
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- echo "running release_job for $TAG"
release:
name: 'Release $TAG'
description: '$EXTRA_DESCRIPTION'
tag_name: '$TAG'
ref: '$CI_COMMIT_SHA'
Job Details
Image: Uses the official GitLab release-cli image
Script: Simple echo statement (the actual release is created via the release: block)
Release Configuration:
- name: Release name (e.g.,
Release v1.0.0) - description: Release description with version and date
- tag_name: Git tag name (e.g.,
v1.0.0) - ref: Commit SHA to tag
Complete Pipeline Example
variables:
CONTAINER_REGISTRY_ID: 4495833
DOCKER_BUILD_IMAGE: 'docker:19.03.11'
DOCKER_BUILD_SERVICE: '19.03.11-dind'
CI_TOKEN: '${CI_JOB_TOKEN}'
stages:
- build
- release
# Build job creates pipeline.env
docker-build_job:
stage: build
script:
- docker build -t ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHORT_SHA} .
- docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHORT_SHA}
- echo "${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHORT_SHA}" > pipeline.env
artifacts:
paths:
- pipeline.env
expire_in: 1 hour
.prepare_job:
image: $DOCKER_BUILD_IMAGE
services:
- docker:$DOCKER_BUILD_SERVICE
variables:
REGISTRY_ID: $CONTAINER_REGISTRY_ID
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- apk update
- apk --no-cache add curl
script:
- |
BRANCH_NAME=${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME/\//_}
VERSION=${BRANCH_NAME}
echo VERSION = $VERSION
curl --location --output artifacts.zip --header "Private-Token: ${CI_TOKEN}" "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/artifacts/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME}/download?job=docker-build_job"
unzip -o artifacts.zip
DOCKER_IMAGE=$(cat pipeline.env)
TAG=$(cat pipeline.env| awk -F "_" '{print $2}')
echo "releasing TAG = $TAG"
docker pull ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE}
docker tag ${CI_REGISTRY_IMAGE}:${DOCKER_IMAGE} ${CI_REGISTRY_IMAGE}:${TAG}
docker push ${CI_REGISTRY_IMAGE}:${TAG}
- echo "EXTRA_DESCRIPTION=RELEASE=v${TAG} | DATE=$(date +%Y-%m-%d)" >> variables.env
- echo "TAG=v${TAG}" >> variables.env
artifacts:
reports:
dotenv: variables.env
dependencies:
- docker-build_job
.release_job:
image: registry.gitlab.com/gitlab-org/release-cli:latest
script:
- echo "running release_job for $TAG"
release:
name: 'Release $TAG'
description: '$EXTRA_DESCRIPTION'
tag_name: '$TAG'
ref: '$CI_COMMIT_SHA'
prepare-release:
extends: .prepare_job
stage: release
only:
- merge_requests
create-release:
extends: .release_job
stage: release
dependencies:
- prepare-release
only:
- merge_requests
Workflow
The release process follows this workflow:
- Build Stage: Docker image is built and
pipeline.envis created with image tag - Prepare Stage:
- Downloads artifacts from build job
- Extracts Docker image tag from
pipeline.env - Tags Docker image with release version
- Pushes tagged image
- Exports release variables
- Release Stage: Creates GitLab release with tag and description
Pipeline.env Format
The pipeline.env file should contain the Docker image tag in this format:
{prefix}_{tag}
Example:
release_1.0.0
main_abc12345
The tag extraction uses awk -F "_" '{print $2}' to get the second part after splitting by _.
Prerequisites
- Docker Build Job: A job named
docker-build_jobmust exist and createpipeline.env - Artifacts: The build job must create artifacts containing
pipeline.env - GitLab Token:
CI_TOKENmust have permissions to download artifacts - Docker Registry Access: Registry credentials must be configured
- Docker-in-Docker: Runner must support Docker-in-Docker for image operations
Security Considerations
- CI Token: Store
CI_TOKENas a masked CI/CD variable - Registry Credentials: Store
CI_REGISTRY_USERandCI_REGISTRY_PASSWORDas masked variables - Token Permissions: Ensure the token has read access to artifacts
- Image Tags: Release tags should follow semantic versioning
Notes
- The job downloads artifacts from a specific job (
docker-build_job) in the source branch - Docker image tagging creates a release tag from the build tag
- The release tag format assumes
pipeline.envcontains{prefix}_{tag} - Variables are exported via dotenv artifact for the release job
- The release job uses GitLab's official release-cli
- The job should typically run on merge request pipelines
- Branch names with
/are converted to_for version extraction - The release is created at the commit SHA, not at the branch tip