Skip to content

Publish Release

Publish Release #39

name: "Publish Release"
on:
workflow_dispatch:
inputs:
tag:
description: "Existing Tag to Publish (eg: v3.7.0)"
type: string
required: true
dry-run-enabled:
description: "Dry Run Enabled"
type: boolean
required: false
default: false
push:
tags:
- "v*.*.*"
defaults:
run:
shell: bash
permissions:
contents: write
jobs:
validate-release:
name: Validate Release
runs-on: [self-hosted, Linux, medium, ephemeral]
outputs:
tag: ${{ steps.tag.outputs.name }}
version: ${{ steps.tag.outputs.version }}
prerelease: ${{ steps.tag.outputs.prerelease }}
type: ${{ steps.tag.outputs.type }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
egress-policy: audit
- name: Checkout Code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
ref: ${{ github.event.inputs.tag || '' }}
fetch-depth: 0
- name: Install Semantic Version Tools
run: |
echo "::group::Download SemVer Binary"
sudo curl -L -o /usr/local/bin/semver https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver
echo "::endgroup::"
echo "::group::Change SemVer Binary Permissions"
sudo chmod -v +x /usr/local/bin/semver
echo "::endgroup::"
echo "::group::Show SemVer Binary Version Info"
semver --version
echo "::endgroup::"
- name: Setup JQ
uses: dcarbone/install-jq-action@1090b8bd111c736fbfe29b686e64f4bec7b5caa6 # v2.0.2
with:
version: 1.7
- name: Extract NPM Package Information
id: npm-package
run: echo "version=$(jq -r '.version' package.json)" >>"${GITHUB_OUTPUT}"
- name: Extract Tag Information
id: tag
run: |
set -x
REF_NAME="$(git describe --exact-match --tags $(git log -n1 --pretty='%h'))"
IS_VALID_SEMVER="$(semver validate "${REF_NAME}")"
if [[ "${IS_VALID_SEMVER}" != "valid" ]]; then
echo "::error title=Invalid Tag::The tag '${REF_NAME}' is not a valid SemVer tag."
exit 1
fi
RELEASE_VERSION="$(semver get release "${REF_NAME}")"
PREREL_VERSION="$(semver get prerel "${REF_NAME}")"
PREREL_VERSION_LC="$(printf "%s" "${PREREL_VERSION}" | tr '[:upper:]' '[:lower:]')"
IS_PRERELEASE="false"
[[ -n "${PREREL_VERSION}" ]] && IS_PRERELEASE="true"
PREREL_TYPE="unknown"
if [[ "${IS_PRERELEASE}" == "true" ]]; then
if [[ "${PREREL_VERSION_LC}" =~ "beta" ]]; then
PREREL_TYPE="beta"
else
PREREL_TYPE="unknown"
fi
else
PREREL_TYPE="production"
fi
FINAL_VERSION="${RELEASE_VERSION}"
[[ -n "${PREREL_VERSION}" ]] && FINAL_VERSION="${RELEASE_VERSION}-${PREREL_VERSION}"
TAG_NAME="v${FINAL_VERSION}"
echo "name=${TAG_NAME}" >>"${GITHUB_OUTPUT}"
echo "version=${FINAL_VERSION}" >>"${GITHUB_OUTPUT}"
echo "prerelease=${IS_PRERELEASE}" >>"${GITHUB_OUTPUT}"
echo "type=${PREREL_TYPE}" >>"${GITHUB_OUTPUT}"
set +x
- name: Validate Tag and Package Versions
run: |
set -x
COMPARISON_RESULT="$(semver compare "${{ steps.npm-package.outputs.version }}" "${{ steps.tag.outputs.version }}")"
if [[ "${COMPARISON_RESULT}" -ne 0 ]]; then
echo "::error title=Version Mismatch::The version in package.json (${{ steps.npm-package.outputs.version }}) does not match the version in the tag (${{ steps.tag.outputs.version }})."
exit 1
fi
if [[ "${{ steps.tag.outputs.type }}" != "production" && "${{ steps.tag.outputs.type }}" != "beta" ]]; then
echo "::error title=Unsupported PreRelease::The tag '${{ steps.tag.outputs.name }}' is an unsupported prerelease tag. Only 'beta' prereleases are supported."
exit 2
fi
if [[ "${{ steps.tag.outputs.type }}" != "production" && "${{ steps.tag.outputs.type }}" != "beta" ]]; then
echo "::error title=Unsupported PreRelease::The tag '${{ steps.tag.outputs.name }}' is an unsupported prerelease tag. Only 'beta' prereleases are supported."
exit 2
fi
set +x
run-safety-checks:
name: Safety Checks
runs-on: [self-hosted, Linux, medium, ephemeral]
steps:
- name: Harden Runner
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
egress-policy: audit
- name: Checkout Code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
ref: ${{ github.event.inputs.tag || '' }}
- name: Install Task
uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2.0.0
with:
version: 3.35.1
- name: Install PNPM
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
with:
version: 8.15.4
- name: Setup Node
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 18
- name: Compile Code
run: task -v build
publish-release:
name: Publish Release
runs-on: [self-hosted, Linux, large, ephemeral]
needs:
- validate-release
- run-safety-checks
steps:
- name: Harden Runner
uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0
with:
egress-policy: audit
- name: Checkout Code
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
ref: ${{ github.event.inputs.tag || '' }}
- name: Install Task
uses: arduino/setup-task@b91d5d2c96a56797b48ac1e0e89220bf64044611 # v2.0.0
with:
version: 3.35.1
- name: Install PNPM
uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
with:
version: 8.15.4
- name: Setup Node
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 18
cache: pnpm
- name: Install NPM Dependencies
run: task -v install
- name: Install Playwright Dependencies
run: sudo npx playwright install-deps
- name: Check Proto Subpackage Publish Status
id: proto
working-directory: packages/proto
run: |
PACKAGE_VERSION="$(node -p "require('./package.json').version")"
PUBLISH_REQUIRED="false"
if ! curl -sSLf "https://registry.npmjs.org/@hashgraph/proto/${PACKAGE_VERSION}" >/dev/null 2>&1; then
PUBLISH_REQUIRED="true"
fi
echo "version=${PACKAGE_VERSION}" >>"${GITHUB_OUTPUT}"
echo "publish-required=${PUBLISH_REQUIRED}" >>"${GITHUB_OUTPUT}"
- name: Check Cryptography Subpackage Publish Status
id: cryptography
working-directory: packages/cryptography
run: |
PACKAGE_VERSION="$(node -p "require('./package.json').version")"
PUBLISH_REQUIRED="false"
if ! curl -sSLf "https://registry.npmjs.org/@hashgraph/cryptography/${PACKAGE_VERSION}" >/dev/null 2>&1; then
PUBLISH_REQUIRED="true"
fi
echo "version=${PACKAGE_VERSION}" >>"${GITHUB_OUTPUT}"
echo "publish-required=${PUBLISH_REQUIRED}" >>"${GITHUB_OUTPUT}"
- name: Calculate Publish Arguments
id: publish
run: |
PUBLISH_ARGS="--access public --no-git-checks"
[[ "${{ github.event.inputs.dry-run-enabled }}" == "true" ]] && PUBLISH_ARGS="${PUBLISH_ARGS} --dry-run"
[[ "${{ needs.validate-release.outputs.prerelease }}" == "true" ]] && PUBLISH_ARGS="${PUBLISH_ARGS} --tag ${{ needs.validate-release.outputs.type }}"
echo "args=${PUBLISH_ARGS}" >>"${GITHUB_OUTPUT}"
# Add the registry authentication stanza with variable substitution to the .npmrc configuration file.
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >>".npmrc"
- name: Publish Proto Release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
working-directory: packages/proto
if: ${{ steps.proto.outputs.publish-required == 'true' && !cancelled() && !failure() }}
run: |
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >>".npmrc"
task -v publish -- ${{ steps.publish.outputs.args }}
- name: Publish Cryptography Release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
working-directory: packages/cryptography
if: ${{ steps.cryptography.outputs.publish-required == 'true' && !cancelled() && !failure() }}
run: |
echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >>".npmrc"
task -v publish -- ${{ steps.publish.outputs.args }}
- name: Publish SDK Release
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: task -v publish -- ${{ steps.publish.outputs.args }}
- name: Generate Github Release
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
if: ${{ github.event.inputs.dry-run-enabled != 'true' && !cancelled() && !failure() }}
with:
tag: ${{ steps.validate-release.outputs.tag }}
prerelease: ${{ needs.validate-release.outputs.prerelease == 'true' }}
draft: false
generateReleaseNotes: true
skipIfReleaseExists: true