Build,Publish Docker and NPM #9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: 'Build,Publish Docker and NPM' | |
on: | |
workflow_dispatch: | |
inputs: | |
docker_user: | |
description: 'Docker Username' | |
required: true | |
docker_token: | |
description: 'Docker Token' | |
required: true | |
npm_token: | |
description: 'NPM Token' | |
required: true | |
permissions: | |
contents: write | |
env: | |
DOCKER_IMAGE_NAME: wifidb/contour-generator | |
jobs: | |
release-check: | |
name: Check if version is published | |
runs-on: ubuntu-latest | |
defaults: | |
run: | |
shell: bash | |
steps: | |
- uses: actions/checkout@v5 | |
- uses: actions/setup-node@v4 | |
with: | |
node-version-file: 'package.json' | |
check-latest: true | |
cache: 'npm' | |
- name: Install NPM dependencies 🚀 | |
run: npm ci | |
- name: Check if version is published | |
id: check | |
run: | | |
PACKAGE_VERSION="$( node -e "console.log(require('./package.json').version)" )" | |
RELEASE_TYPE="$(node -e "const semver = require('semver'); const prerelease = semver.prerelease('$PACKAGE_VERSION'); console.log(prerelease ? 'prerelease' : 'regular')")" | |
isPublished="$( npm view @acalcutt/contour-generator versions --json | jq -c --arg cv "$PACKAGE_VERSION" 'any(. == $cv)' )" | |
echo "version=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT" | |
echo "published=$isPublished" >> "$GITHUB_OUTPUT" | |
echo "release_type=$RELEASE_TYPE" >> "$GITHUB_OUTPUT" | |
echo "PACKAGE_VERSION: $PACKAGE_VERSION" | |
echo "RELEASE_TYPE: $RELEASE_TYPE" | |
echo "isPublished: $isPublished" | |
outputs: | |
published: ${{ steps.check.outputs.published }} | |
version: ${{ steps.check.outputs.version }} | |
release_type: ${{ steps.check.outputs.release_type }} | |
# Build and push individual architecture images (with tests) | |
build_docker_images: | |
name: Build Docker ${{ matrix.arch }} Image | |
runs-on: ${{ matrix.runs-on }} | |
needs: release-check | |
if: ${{ needs.release-check.outputs.published == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- runs-on: ubuntu-24.04 | |
arch: amd64 | |
- runs-on: ubuntu-24.04-arm | |
arch: arm64 | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login to DockerHub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ github.event.inputs.docker_user }} | |
password: ${{ github.event.inputs.docker_token }} | |
# Build and Push Main Image | |
- name: Build and Push Main ${{ matrix.arch }} Image | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
push: true | |
platforms: linux/${{ matrix.arch }} | |
tags: | | |
${{ env.DOCKER_IMAGE_NAME }}:v${{ needs.release-check.outputs.version }}-${{ matrix.arch }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
# Create manifests, publish NPM, and create GitHub release | |
release: | |
name: Release | |
runs-on: ubuntu-latest | |
needs: [release-check, build_docker_images] | |
if: ${{ needs.release-check.outputs.published == 'false' }} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v5 | |
- name: Setup node env 📦 | |
uses: actions/setup-node@v4 | |
with: | |
node-version-file: 'package.json' | |
check-latest: true | |
cache: 'npm' | |
- name: Install NPM dependencies 🚀 | |
run: npm ci | |
- name: Get release type | |
id: prepare_release | |
run: | | |
if [[ ${{ needs.release-check.outputs.release_type }} == 'regular' ]]; then | |
echo "prerelease=false" >> "$GITHUB_OUTPUT" | |
echo "tag=latest" >> "$GITHUB_OUTPUT" | |
else | |
echo "prerelease=true" >> "$GITHUB_OUTPUT" | |
echo "tag=next" >> "$GITHUB_OUTPUT" | |
fi | |
# NPM Publishing | |
- name: Publish to NPM | |
run: | | |
npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} | |
npm publish --access public --tag ${{ steps.prepare_release.outputs.tag }} | |
env: | |
NPM_TOKEN: ${{ github.event.inputs.npm_token }} | |
# Docker Manifest Creation | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login to DockerHub | |
uses: docker/login-action@v3 | |
with: | |
username: ${{ github.event.inputs.docker_user }} | |
password: ${{ github.event.inputs.docker_token }} | |
- name: Create and push Main Multi-Arch Manifest | |
run: | | |
PACKAGE_VERSION="${{ needs.release-check.outputs.version }}" | |
docker buildx imagetools create \ | |
--tag "${{ env.DOCKER_IMAGE_NAME }}:${{ steps.prepare_release.outputs.tag }}" \ | |
--tag "${{ env.DOCKER_IMAGE_NAME }}:v${PACKAGE_VERSION}" \ | |
"${{ env.DOCKER_IMAGE_NAME }}:v${PACKAGE_VERSION}-amd64" \ | |
"${{ env.DOCKER_IMAGE_NAME }}:v${PACKAGE_VERSION}-arm64" | |
# GitHub Release | |
- name: Extract changelog for version | |
run: | | |
awk '/^##/ { p = 0 }; p == 1 { print }; $0 == "## ${{ needs.release-check.outputs.version }}" { p = 1 };' CHANGELOG.md > changelog_for_version.md | |
cat changelog_for_version.md | |
- name: Publish to GitHub Release | |
uses: ncipollo/release-action@v1 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
with: | |
tag: v${{ needs.release-check.outputs.version }} | |
name: v${{ needs.release-check.outputs.version }} | |
bodyFile: changelog_for_version.md | |
allowUpdates: true | |
draft: false | |
prerelease: ${{ steps.prepare_release.outputs.prerelease }} |