publish(npm): automate Package Versioning and Publishing with Changes… #21
This file contains 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
# Run it locally with act | |
# 1. Install act: https://github.com/nektos/act/releases | |
# 2. Create a .secret file in the root of this repository with the following content: | |
# `GITHUB_TOKEN=your_github_token` and `ACT=true` | |
# Note: to create a token... | |
# * Log in to your GitHub account and go to your profile settings. | |
# * In the left sidebar, click on "Developer settings". | |
# * Select "Personal access tokens" from the menu. | |
# * Click on "Generate new token" (classic or fine-grained). and choose `public_repoAccess` | |
# * Copy the token and use it in the .secrets file | |
# 3. Trigger the workflow with act: | |
# `act workflow_dispatch --container-architecture linux/amd64 -P default=catthehacker/ubuntu:act-latest -W .github/workflows/build-push-greenhouse-image.yaml` | |
name: Build Greenhouse Dashboard 💚 | |
on: | |
workflow_dispatch: {} | |
push: | |
branches: | |
- main | |
paths: | |
- apps/greenhouse/CHANGELOG.md | |
env: | |
REGISTRY: ghcr.io | |
IMAGE_NAME: "juno-app-greenhouse" | |
PACKAGE_PATH: "apps/greenhouse" | |
jobs: | |
build-and-push-greenhouse-image: | |
name: Build and Push Greenhouse Dashboard Image | |
runs-on: [default] | |
permissions: | |
contents: read | |
packages: write | |
# This is used to complete the identity challenge | |
# with sigstore/fulcio when running outside of PRs. | |
id-token: write | |
security-events: write | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Read version from package.json | |
id: read_version | |
working-directory: ${{ env.PACKAGE_PATH }} | |
run: | | |
# Extract the first version number that appears after "## " | |
GREENHOUSE_VERSION=$(jq -r '.version' package.json) | |
echo "Greenhouse version is $GREENHOUSE_VERSION" | |
echo "IMAGE_VERSION=$GREENHOUSE_VERSION" >> $GITHUB_OUTPUT | |
- name: Read description from README.md | |
id: description | |
working-directory: ${{ env.PACKAGE_PATH }} | |
run: | | |
# Concatenate CHANGELOG.md | |
echo "DESCRIPTION=$(head -c 512 apps/greenhouse/README.md)" >> $GITHUB_OUTPUT | |
# Login against a Docker registry except on PR | |
# https://github.com/docker/login-action | |
- name: Log into registry ${{ env.REGISTRY }} | |
if: github.event_name != 'pull_request' | |
uses: docker/login-action@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
# and check if the image with the same version already exists | |
- name: Check if image exists ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ steps.read_version.outputs.IMAGE_VERSION }} in registry | |
id: check-image | |
run: | | |
# If the image with this tag already exists, this command will exit with status code 1. | |
if docker pull ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ steps.read_version.outputs.IMAGE_VERSION }}; then | |
echo "Image ${{ env.IMAGE_NAME }}:${{ steps.read_version.outputs.IMAGE_VERSION }} already exists in the registry" | |
exit 1 | |
fi | |
# This action enables you to SIGN and VERIFY container images using cosign | |
- name: Install cosign | |
uses: sigstore/[email protected] | |
with: | |
cosign-release: "v2.4.0" | |
# Set up BuildKit Docker container builder to be able to build MULTI-platform images and export cache | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
with: | |
driver-opts: | | |
image=moby/buildkit:latest | |
- name: Generate Docker metadata | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }} | |
tags: | | |
type=semver,pattern={{major}}.{{minor}}.{{patch}},value=${{ steps.read_version.outputs.IMAGE_VERSION }} | |
# Build and load to Docker | |
- name: Build and export to Docker ${{ steps.meta.outputs.tags }} | |
id: build-image | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
file: ${{ env.PACKAGE_PATH }}/docker/Dockerfile | |
load: true # load the image into the docker daemon to make the image available for the next steps in the workflow | |
tags: ${{ steps.meta.outputs.tags }} | |
outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=${{ steps.description.outputs.DESCRIPTION }} | |
- name: Run Trivy vulnerability scanner | |
uses: aquasecurity/trivy-action@master | |
with: | |
image-ref: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest | |
format: "sarif" | |
exit-code: "0" | |
ignore-unfixed: true | |
severity: "CRITICAL,HIGH" | |
output: "trivy-results.sarif" | |
- name: Upload Trivy scan results to GitHub Security tab | |
uses: github/codeql-action/upload-sarif@v3 | |
if: ${{ always() && !env.ACT }} | |
with: | |
sarif_file: trivy-results.sarif | |
- name: Push Docker image | |
if: ${{ !env.ACT }} | |
run: | | |
# upload all images to the registry | |
TAGS=$(echo "${{ steps.meta.outputs.tags }}") | |
printf '%s\n' "$TAGS" | while IFS= read -r tag; do | |
echo "Upload image: $tag" | |
docker push $tag | |
done | |
- name: Sign the published Docker image | |
if: ${{ !env.ACT }} | |
env: | |
TAGS: ${{ steps.meta.outputs.tags }} | |
DIGEST: ${{ steps.build-image.outputs.digest }} | |
# This step uses the identity token to provision an ephemeral certificate | |
# against the sigstore community Fulcio instance. | |
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} | |
notify-on-failure: | |
if: failure() | |
needs: [build-and-push-greenhouse-image] | |
uses: cloudoperators/juno/.github/workflows/shared-slack-notification.yaml@main | |
with: | |
title: "🚨 JUNO Greenhouse Image Failed 🚨" | |
body: "An error occurred while building the Greenhouse image for the branch ${{ github.head_ref || github.ref_name }}. Please check the logs for more information. <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Check the logs>" | |
secrets: | |
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} |