Skip to content

Avoid using ephemeral runners in publishing workflows since ephemeral runners are new feature and using them during the release can complicate the process. #1342

Avoid using ephemeral runners in publishing workflows since ephemeral runners are new feature and using them during the release can complicate the process.

Avoid using ephemeral runners in publishing workflows since ephemeral runners are new feature and using them during the release can complicate the process. #1342

Workflow file for this run

# The cross platform build was created based on the [Packaging Rust Applications for the NPM Registry blog](https://blog.orhun.dev/packaging-rust-for-npm/).
name: NPM - Continuous Deployment
on:
pull_request:
paths:
- .github/workflows/npm-cd.yml
- .github/workflows/build-node-wrapper/action.yml
- .github/workflows/start-self-hosted-runner/action.yml
- .github/workflows/install-rust-and-protoc/action.yml
- .github/workflows/install-shared-dependencies/action.yml
- .github/workflows/install-engine/action.yml
- .github/json_matrices/**
- .github/workflows/create-test-matrices/action.yml
push:
tags:
- "v*.*"
workflow_dispatch:
inputs:
version:
description: "The release version of GLIDE, formatted as *.*.* or *.*.*-rc*"
required: true
concurrency:
group: node-cd-${{ github.head_ref || github.ref }}-${{ toJson(inputs) }}
cancel-in-progress: true
permissions:
id-token: write
jobs:
start-self-hosted-runner:
if: github.repository_owner == 'valkey-io'
runs-on: ubuntu-latest
environment: AWS_ACTIONS
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Start self hosted EC2 runner
uses: ./.github/workflows/start-self-hosted-runner
with:
role-to-assume: ${{ secrets.ROLE_TO_ASSUME }}
aws-region: ${{ secrets.AWS_REGION }}
ec2-instance-id: ${{ secrets.AWS_EC2_INSTANCE_ID }}
load-platform-matrix:
runs-on: ubuntu-latest
outputs:
PLATFORM_MATRIX: ${{ steps.load-platform-matrix.outputs.PLATFORM_MATRIX }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: load-platform-matrix
id: load-platform-matrix
shell: bash
run: |
# Filter entries with npm in PACKAGE_MANAGERS and remove "ephemeral" from RUNNER
export PLATFORM_MATRIX=$(jq 'map(
select(.PACKAGE_MANAGERS != null and (.PACKAGE_MANAGERS | contains(["npm"])))
| .RUNNER = (
if (type == "array")
then (.RUNNER | map(select(. != "ephemeral")))
else .RUNNER
end
)
)' < .github/json_matrices/build-matrix.json | jq -c .)
echo "PLATFORM_MATRIX=${PLATFORM_MATRIX}" >> $GITHUB_OUTPUT
publish-binaries:
needs: [start-self-hosted-runner, load-platform-matrix]
if: github.repository_owner == 'valkey-io'
name: Publish packages to NPM
runs-on: ${{ matrix.build.RUNNER }}
container:
image: ${{ matrix.build.IMAGE || '' }}
options: ${{ matrix.build.CONTAINER_OPTIONS || 'none'}}
strategy:
fail-fast: false
matrix:
build: ${{fromJson(needs.load-platform-matrix.outputs.PLATFORM_MATRIX)}}
steps:
- name: Setup self-hosted runner access
if: ${{ contains(matrix.build.RUNNER, 'self-hosted') && matrix.build.TARGET != 'aarch64-unknown-linux-musl' }}
run: sudo chown -R $USER:$USER /home/ubuntu/actions-runner/_work/valkey-glide
# For MUSL on X64 we need to install git since we use the checkout action
- name: Install git for musl
if: ${{ contains(matrix.build.TARGET, 'x86_64-unknown-linux-musl')}}
run: |
apk update
apk add git
- name: Checkout
if: ${{ matrix.build.TARGET != 'aarch64-unknown-linux-musl' }}
uses: actions/checkout@v4
with:
submodules: "true"
fetch-depth: 0
- name: Setup for musl
if: ${{ contains(matrix.build.TARGET, 'musl')}}
uses: ./.github/workflows/setup-musl-on-linux
with:
workspace: $GITHUB_WORKSPACE
npm-scope: ${{ vars.NPM_SCOPE }}
npm-auth-token: ${{ secrets.NPM_AUTH_TOKEN }}
arch: ${{ matrix.build.ARCH }}
- name: Set the release version
shell: bash
run: |
if ${{ env.EVENT_NAME == 'pull_request' }}; then
R_VERSION="255.255.255"
elif ${{ env.EVENT_NAME == 'workflow_dispatch' }}; then
echo "${{env.EVENT_NAME}}"
R_VERSION="${{ env.INPUT_VERSION }}"
else
R_VERSION=${GITHUB_REF:11}
fi
echo "RELEASE_VERSION=${R_VERSION}" >> $GITHUB_ENV
env:
EVENT_NAME: ${{ github.event_name }}
INPUT_VERSION: ${{ github.event.inputs.version }}
- name: Setup node
if: ${{ !contains(matrix.build.TARGET, 'musl') }}
uses: actions/setup-node@v4
with:
node-version: "latest"
registry-url: "https://registry.npmjs.org"
architecture: ${{ matrix.build.ARCH }}
scope: "${{ vars.NPM_SCOPE }}"
always-auth: true
token: ${{ secrets.NPM_AUTH_TOKEN }}
- name: Setup node for publishing
if: ${{ !contains(matrix.build.TARGET, 'musl') }}
working-directory: ./node
run: |
npm config set registry https://registry.npmjs.org/
npm config set '//registry.npmjs.org/:_authToken' ${{ secrets.NPM_AUTH_TOKEN }}
npm config set scope ${{ vars.NPM_SCOPE }}
- name: Update package version in config.toml
uses: ./.github/workflows/update-glide-version
with:
folder_path: "${{ github.workspace }}/node/rust-client/.cargo"
named_os: ${{ matrix.build.NAMED_OS }}
- name: Build Node wrapper
uses: ./.github/workflows/build-node-wrapper
with:
os: ${{ matrix.build.OS }}
named_os: ${{ matrix.build.NAMED_OS }}
arch: ${{ matrix.build.ARCH }}
target: ${{ matrix.build.TARGET }}
npm_scope: ${{ vars.NPM_SCOPE }}
publish: "true"
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check if RC and set a distribution tag for the package
shell: bash
run: |
if [[ "${GITHUB_REF:11}" == *"rc"* ]]
then
echo "This is a release candidate: ${GITHUB_REF:11}"
export npm_tag="next"
else
echo "This is a stable release: ${GITHUB_REF:11}"
export npm_tag="latest"
fi
echo "NPM_TAG=${npm_tag}" >> $GITHUB_ENV
- name: Check that the release version dont have typo init
if: ${{ github.event_name != 'pull_request' && contains(env.RELEASE_VERSION, '-') && !contains(env.RELEASE_VERSION, 'rc') }}
run: |
echo "The release version "${GITHUB_REF:11}" contains a typo, please fix it"
echo "The release version should be in the format v{major-version}.{minor-version}.{patch-version}-rc{release-candidate-number} when it a release candidate or v{major-version}.{minor-version}.{patch-version} in a stable release."
exit 1
- name: Publish to NPM
if: github.event_name != 'pull_request'
shell: bash
working-directory: ./node
run: |
npm pkg fix
set +e # Disable immediate exit on non-zero exit codes
# Redirect stderr to stdout, filter out notices and warnings
{ npm_publish_err=$(npm publish --tag "${NPM_TAG}" --access public --loglevel=error 2>&1 1>&3- | grep -Ev "notice|ExperimentalWarning|WARN") ;} 3>&1
publish_exit_code=$?
# Re-enable immediate exit
set -e
if [[ $publish_exit_code -eq 0 ]]; then
echo "Package published successfully."
elif echo "$npm_publish_err" | grep -q "You cannot publish over the previously published versions"; then
echo "Skipping publishing, package already published."
elif [[ ! -z "$npm_publish_err" ]]; then
echo "Failed to publish with error: $npm_publish_err"
exit 1
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
# Reset the repository to make sure we get the clean checkout of the action later in other actions.
# It is not required since in other actions we are cleaning before the action, but it is a good practice to do it here as well.
- name: Reset repository
if: ${{ matrix.build.ARCH == 'arm64' }}
shell: bash
run: |
echo "Resetting repository"
git clean -xdf
git reset --hard
git fetch
git checkout ${{ github.sha }}
publish-base-to-npm:
if: github.event_name != 'pull_request'
name: Publish the base NPM package
needs: publish-binaries
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: "true"
- name: Install node
uses: actions/setup-node@v4
with:
node-version: "latest"
registry-url: "https://registry.npmjs.org"
scope: "${{ vars.NPM_SCOPE }}"
always-auth: true
- name: Create package.json file
shell: bash
working-directory: ./node/npm/glide
run: |
export pkg_name=valkey-glide
echo "The workflow is: ${{env.EVENT_NAME}}"
if ${{ env.EVENT_NAME == 'workflow_dispatch' }}; then
R_VERSION="${{ env.INPUT_VERSION }}"
else
R_VERSION=${GITHUB_REF:11}
fi
echo "RELEASE_VERSION=${R_VERSION}" >> $GITHUB_ENV
export package_version=${R_VERSION}
export scope=`if [ "$NPM_SCOPE" != '' ]; then echo "$NPM_SCOPE/"; fi`
mv package.json package.json.tmpl
envsubst < package.json.tmpl > "package.json"
cat package.json
# Fix index.ts based on the scope variable
sed -i "s|@scope/|${scope}|g" index.ts
env:
NPM_SCOPE: ${{ vars.NPM_SCOPE }}
EVENT_NAME: ${{ github.event_name }}
INPUT_VERSION: ${{ github.event.inputs.version }}
- name: Build Node wrapper
uses: ./.github/workflows/build-node-wrapper
with:
os: ubuntu
target: "x86_64-unknown-linux-gnu"
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Check if RC and set a distribution tag for the package
shell: bash
run: |
if [[ ${{ env.RELEASE_VERSION }} == *"rc"* ]]
then
echo "This is a release candidate"
export npm_tag="next"
else
echo "This is a stable release"
export npm_tag="latest"
fi
echo "NPM_TAG=${npm_tag}" >> $GITHUB_ENV
- name: Publish the base package
if: github.event_name != 'pull_request'
shell: bash
working-directory: ./node/npm/glide
run: |
# Copy the main README file
cp ../../README.md .
npm install
npm run build
npm publish --access public --tag ${{ env.NPM_TAG }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
test-release:
if: github.event_name != 'pull_request'
name: Test the release
needs: [publish-base-to-npm, load-platform-matrix]
runs-on: ${{ matrix.build.RUNNER }}
container:
image: ${{ matrix.build.IMAGE || '' }}
options: ${{ matrix.build.CONTAINER_OPTIONS || 'none'}}
strategy:
fail-fast: false
matrix:
build: ${{fromJson(needs.load-platform-matrix.outputs.PLATFORM_MATRIX)}}
steps:
- name: Setup self-hosted runner access
if: ${{ matrix.build.TARGET == 'aarch64-unknown-linux-gnu' }}
run: sudo chown -R $USER:$USER /home/ubuntu/actions-runner/_work/valkey-glide
- name: install redis and git for alpine
if: ${{ contains(matrix.build.TARGET, 'musl') }}
run: |
apk update
apk add git redis
node -v
- name: install Python for ubuntu
if: ${{ contains(matrix.build.TARGET, 'linux-gnu') }}
run: |
sudo apt-get update
sudo apt-get install python3
- name: Checkout
if: ${{ matrix.build.TARGET != 'aarch64-unknown-linux-musl'}}
uses: actions/checkout@v4
- name: Setup for musl
if: ${{ contains(matrix.build.TARGET, 'musl') }}
uses: ./.github/workflows/setup-musl-on-linux
with:
workspace: $GITHUB_WORKSPACE
npm-scope: ${{ vars.NPM_SCOPE }}
npm-auth-token: ${{ secrets.NPM_AUTH_TOKEN }}
arch: ${{ matrix.build.ARCH }}
- name: Install engine
if: ${{ !contains(matrix.build.TARGET, 'musl') }}
uses: ./.github/workflows/install-engine
with:
engine-version: "8.0"
target: ${{ matrix.build.target }}
- name: Setup node
if: ${{ !contains(matrix.build.TARGET, 'musl') }}
uses: actions/setup-node@v4
with:
node-version: "latest"
registry-url: "https://registry.npmjs.org"
architecture: ${{ matrix.build.ARCH }}
scope: "${{ vars.NPM_SCOPE }}"
always-auth: true
token: ${{ secrets.NPM_AUTH_TOKEN }}
- name: Install tsc and compile utils
shell: bash
working-directory: ./utils
run: |
npm install
npm install -g typescript
npx tsc -p ./tsconfig.json
- name: Check if RC and set a distribution tag for the package
shell: bash
run: |
if [[ "${GITHUB_REF:11}" == *"rc"* ]]
then
echo "This is a release candidate"
export npm_tag="next"
else
echo "This is a stable release"
export npm_tag="latest"
fi
echo "NPM_TAG=${npm_tag}" >> $GITHUB_ENV
- name: Run the tests
shell: bash
working-directory: ./utils/release-candidate-testing/node
run: |
npm install
npm install --no-save @valkey/valkey-glide@${{ env.NPM_TAG }}
npm run test
- name: Deprecating packages on failure
if: ${{ failure() }}
shell: bash
env:
GH_EVENT_NAME: ${{ github.event_name }}
GH_EVENT_INPUT_VERSION: ${{ github.event.inputs.version }}
GH_REF: ${{ github.ref }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
PLATFORM_MATRIX: ${{ needs.load-platform-matrix.outputs.PLATFORM_MATRIX }}
run: |
# Detect OS and install jq
if [[ "${OSTYPE}" == "darwin"* ]]; then
brew install jq || true
elif command -v apk > /dev/null; then
apk add --no-cache jq
else
sudo apt-get update && sudo apt-get install -y jq
fi
# Set RELEASE_VERSION correctly using environment variables
if [[ "${GH_EVENT_NAME}" == "workflow_dispatch" ]]; then
RELEASE_VERSION="${GH_EVENT_INPUT_VERSION}"
else
RELEASE_VERSION="${GH_REF#refs/tags/v}"
fi
# Validate RELEASE_VERSION
if [[ ! "${RELEASE_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$ ]]; then
echo "Invalid release version format: ${RELEASE_VERSION}"
exit 1
fi
echo "Release version for Deprecating: ${RELEASE_VERSION}"
# Deprecating base package
npm deprecate "@valkey/valkey-glide@${RELEASE_VERSION}" "This version has been deprecated" --force || true
# Process platform matrix
echo "${PLATFORM_MATRIX}" > platform_matrix.json
while read -r pkg; do
package_name="@valkey/valkey-glide-${pkg}"
echo "Deprecating ${package_name}@${RELEASE_VERSION}"
npm deprecate "${package_name}@${RELEASE_VERSION}" "This version has been deprecated" --force || true
done < <(jq -r '.[] | "\(.NAMED_OS)\(.TARGET | test("musl") | if . then "-musl" else "" end)-\(.ARCH)"' platform_matrix.json)
# Reset the repository to make sure we get the clean checkout of the action later in other actions.
# It is not required since in other actions we are cleaning before the action, but it is a good practice to do it here as well.
- name: Reset repository
if: ${{ always() }} && ${{ contains(matrix.build.RUNNER, 'self-hosted') }}
shell: bash
run: |
git reset --hard
git clean -xdf