Skip to content

Publishing to GitHub Packages #3498

Publishing to GitHub Packages

Publishing to GitHub Packages #3498

name: Publishing to GitHub Packages
on:
workflow_dispatch:
inputs:
tag:
description: "Choose a tag: 'daily' when publishing a daily build with a timestamp version, 'stable' when publishing a stable build from a release branch"
type: choice
options:
- daily
- stable
default: 'daily'
required: false
filter:
type: string
description: Package file filter pattern
required: false
env:
NX_SKIP_NX_CACHE: true
FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }}
SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }}
CYCLONEDX_CLI_VERSION: 0.32.0
jobs:
build:
name: Build packages
runs-on: windows-latest
outputs:
packages: ${{ steps.filter.outputs.packages }}
steps:
- name: Get sources
uses: actions/checkout@v4
- name: Set up nodejs
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
- uses: pnpm/action-setup@v4
with:
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "PNPM_STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Set timestamp version
if: ${{ env.SET_TIMESTAMP_VERSION == 'true' }}
run: pnpm run all:set-timestamp-version
- name: Build npm packages
env:
BUILD_INTERNAL_PACKAGE: true
run: pnpm run all:build
- name: Clone deps scanner
uses: actions/checkout@v4
with:
repository: DevExpress/npmdeps-scanner
token: ${{ secrets.NPM_DEPS_SCANNER_PAT }}
path: deps-scanner
- name: Build deps scanner
working-directory: deps-scanner
run: dotnet build npmDepsScanner.csproj /p:Configuration=Release
- name: Run deps scanner
run: |
./deps-scanner/bin/Release/npmDepsScanner.exe scan_cache ${{ github.workspace }} reportGithub.json
mkdir -p ./artifacts/deps-scanner
cp reportGithub.json ./artifacts/deps-scanner/
- name: Build SBOMs
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
pnpm set "//npm.pkg.github.com/:_authToken" "$env:NODE_AUTH_TOKEN"
pnpm nx build sbom;
- name: Install CycloneDX CLI
shell: bash
run: |
# extract to sbom pnpm project / scripts? (./packages/sbom/project.json)
tool_dir="$RUNNER_TEMP/cyclonedx-cli"
mkdir -p "$tool_dir"
curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-win-x64.exe" -o "$tool_dir/cyclonedx.exe"
chmod +x "$tool_dir/cyclonedx.exe" || true
echo "$tool_dir" >> "$GITHUB_PATH"
- name: Validate CycloneDX SBOMs
shell: bash
run: |
shopt -s nullglob
sbom_files=(packages/sbom/dist/*.sbom.json)
if [ ${#sbom_files[@]} -eq 0 ]; then
echo "No SBOM files found in packages/sbom/dist"
exit 1
fi
for file in "${sbom_files[@]}"; do
echo "Validating $file"
cyclonedx validate --input-file "$file" --input-format json --fail-on-errors
done
- name: Build artifacts package
run: pnpm run make-artifacts-package
- name: Upload SBOM artifact
uses: actions/upload-artifact@v4
with:
name: sbom
path: packages/sbom/dist
retention-days: 7
- name: Upload packages
uses: actions/upload-artifact@v4
with:
name: packages
path: artifacts/npm/*.tgz
retention-days: 2
- name: Filter packages
id: filter
working-directory: artifacts/npm
shell: bash
run: ls *.tgz | grep -E -i "$FILTER" | sed -r 's/^(.*).tgz$/"\1"/g' | paste -sd "," - | sed -r 's/(.*)/packages=[\1]/' >> "$GITHUB_OUTPUT"
publish:
name: Publish package
runs-on: ubuntu-latest
needs: build
strategy:
fail-fast: false
matrix:
package: ${{ fromJSON(needs.build.outputs.packages) }}
steps:
- name: Get sources
uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: packages
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
- uses: pnpm/action-setup@v4
with:
run_install: false
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Change package scope
id: scopedPackage
env:
PACKAGE: ${{ matrix.package }}
run: |
SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]');
PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz $PACKAGE.tgz --scope $SCOPE)
echo "packageDir=$PACKAGE_DIR" >> "$GITHUB_OUTPUT";
cd $PACKAGE_DIR;
pnpm pkg get name --workspaces=false | tr -d '"' | sed -r 's/(.*)/name=\1/' >> "$GITHUB_OUTPUT";
pnpm pkg get version --workspaces=false | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT";
pnpm pkg get version --workspaces=false | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT";
# --ignore-scripts is required for publishing devextreme-angular which fails with error:
# 'Trying to publish a package that has been compiled by Ivy in full compilation mode.'
# Should be removed.
- name: Publish to npm.pkg.github.com
working-directory: ${{ steps.scopedPackage.outputs.packageDir }}
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PACKAGE_NAME: ${{ steps.scopedPackage.outputs.name }}
PACKAGE_VERSION: ${{ steps.scopedPackage.outputs.version }}
PACKAGE_VERSION_MAJOR: ${{ steps.scopedPackage.outputs.majorVersion }}
run: |
pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN";
pnpm publish --no-git-checks --quiet --ignore-scripts --tag $PACKAGE_VERSION_MAJOR-${{ inputs.tag }} --registry https://npm.pkg.github.com;
pnpm dist-tag add $PACKAGE_NAME@$PACKAGE_VERSION latest --registry=https://npm.pkg.github.com;
notify:
runs-on: devextreme-shr2
name: Send notifications
needs: [ build, publish ]
if: failure()
steps:
- uses: actions/checkout@v4
- uses: DevExpress/github-actions/send-teams-notification@v1
with:
hook_url: ${{secrets.TEAMS_ALERT}}
bearer_token: ${{secrets.GITHUB_TOKEN}}
specific_repo: DevExpress/DevExtreme