Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/docker-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright (c) 2024 Hemi Labs, Inc.
# Use of this source code is governed by the MIT License,
# which can be found in the LICENSE file.

name: Docker Checks

on:
workflow_call:
inputs:
context:
description: "The build context"
default: "."
type: string
fetch-depth:
description: Number of commits to fetch. 0 indicates all history for all branches and tags.
default: 1
type: number

jobs:
docker-checks:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: docker build --tag ${{ github.repository }}:${{ github.sha }} ${{ inputs.context }}
- uses: aquasecurity/trivy-action@0.29.0
Comment thread
gabmontes marked this conversation as resolved.
Copy link
Copy Markdown
Contributor

@joshuasing joshuasing Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a third-party action, not maintained by either GitHub or Docker, we should pin it to a commit hash in order to make it immutable.

Suggested change
- uses: aquasecurity/trivy-action@0.29.0
- uses: aquasecurity/trivy-action@76071ef0d7ec797419534a183b498b4d6366cf37 # 0.29.0

https://github.com/aquasecurity/trivy-action/releases/tag/0.31.0
aquasecurity/trivy-action@76071ef

In addition to being third-party, this is also a security scanning tool.

with:
exit-code: 1
ignore-unfixed: true
image-ref: ${{ github.repository }}:${{ github.sha }}
severity: HIGH,CRITICAL
skip-dirs: /root/.npm
21 changes: 14 additions & 7 deletions .github/workflows/js-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,46 @@ name: JS Checks
on:
workflow_call:
inputs:
cache:
description: "Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm."
default: npm
type: string
fetch-depth:
description: Number of commits to fetch. 0 indicates all history for all branches and tags.
default: 1
type: number
node-versions:
description: Array of Node versions to test with (JSON string)
description: Array of Node versions to test with as a JSON string. Default to use the version in the .nvmrc file.
default: "['']"
type: string

jobs:
run-checks:
runs-on: ubuntu-latest
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
with:
fetch-depth: ${{ inputs.fetch-depth }}
- uses: hemilabs/actions/setup-node-env@main
- uses: hemilabs/actions/setup-node-env@v1
with:
cache: ${{ inputs.cache }}
- run: npm run --if-present format:check
- run: npm run --if-present lint
- run: npm run --if-present --include-workspace-root --workspaces deps:check
- run: npm run --if-present --include-workspace-root --workspaces build
run-tests:
runs-on: ubuntu-latest
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
with:
fetch-depth: ${{ inputs.fetch-depth }}
- uses: hemilabs/actions/setup-node-env@main
- uses: hemilabs/actions/setup-node-env@v1
with:
cache: ${{ inputs.cache }}
node-version: ${{ matrix.node-version }}
- run: npm run --if-present --include-workspace-root --workspaces test
strategy:
Expand Down
10 changes: 4 additions & 6 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,15 @@ on:

jobs:
publish-to-npm:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/checkout@v4
Comment thread
joshuasing marked this conversation as resolved.
with:
fetch-depth: ${{ inputs.fetch-depth }}
- uses: hemilabs/actions/setup-node-env@main
- run: npm run --if-present prepublishOnly
- uses: JS-DevTools/npm-publish@9ff4ebfbe48473265867fb9608c047e7995edfa3 # v3.1.1
- uses: hemilabs/actions/publish-to-npm@v1
with:
provenance: true
provenance: "true"
token: ${{ secrets.NPM_TOKEN }}
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,47 @@
Contains reusable GitHub Actions and GitHub Actions workflows for the [Hemi Labs](https://github.com/hemilabs)'s
repositories.

## Actions

- `docker-build-push`: Build and push Docker images to Docker Hub.
- `notify-deploy-to-slack`: Sends a notification to Slack using a pre-configured webhook.
- `publish-to-npm`: Sets up Node, runs the prepublishOnly script and publishes the package to the NPM registry.
- `setup-node-env`: Sets up Node, restores NPM cache and installs dependencies.

## Reusable workflows

- `deploy-kustomize`: Deploy to Kubernetes using Kustomize.
- `docker-checks`: Locally builds a Docker image and uses `aquasecurity/trivy-action` to check for vulnerabilities.
- `docker-registry-secret`: Create a Docker Hub secret.
- `docker`: Build and push docker images.
- `js-checks`: Run standard checks as linter, code formatter; then run tests against different Node versions.
- `npm-publish`: Publish a package to NPM.

## Usage

To use the actions and workflows in this repository, add a reference as follows:

```yml
# .github/workflows/example.yml

jobs:
job-one:
steps:
- uses: hemilabs/actions/setup-node-env@v1.0.0
job-two:
uses: hemilabs/actions/.github/workflows/js-checks.yml@v1
```

See the GitHub Actions docs for details about [how to use a public action](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#example-using-a-public-action) and how to reference a [reusable workflow](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_iduses).

## Release process

Once the PRs with the changes are approved, either merge the branch locally and push `main` or merge the PR in GitHub and pull `main`. Then update and push the tags:

```sh
./bump-version <major, minor, patch>
```

## Contact

If you wish to contact us, please use one of the following methods:
Expand Down
46 changes: 46 additions & 0 deletions bump-version
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about moving this script to scripts/bump-version.sh - to keep it out of the way?
We will likely add additional scripts, so I think having a separate directory would be useful.

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/sh
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is missing a copyright notice:

Suggested change
#!/bin/sh
#!/bin/sh
# Copyright (c) 2025 Hemi Labs, Inc.
# Use of this source code is governed by the MIT License,
# which can be found in the LICENSE file.


set -e

# Get the version part to bump from the command line
if [ -z "$1" ]; then
echo "Use: ./bump-version <major, minor, patch>"
exit 1
fi
PART=$1

# Get the current version parts from the latest tag
LATEST_TAG=$(git tag -l "v*.*.*" --sort=-v:refname | head -n 1)
CURRENT_VERSION=${LATEST_TAG#v}
MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1)
MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2)
PATCH=$(echo "$CURRENT_VERSION" | cut -d. -f3)

# Bump the corresponding version part
case $PART in
major)
MAJOR=$((MAJOR + 1))
MINOR=0
PATCH=0
;;
minor)
MINOR=$((MINOR + 1))
PATCH=0
;;
patch)
PATCH=$((PATCH + 1))
;;
*)
echo "Unknown part '$PART'. Use 'major', 'minor', or 'patch'."
exit 1
;;
esac

# Apply and push the new tags
MAJOR_TAG="v$MAJOR"
NEW_TAG="$MAJOR_TAG.$MINOR.$PATCH"
git tag --force --message="" --sign "$MAJOR_TAG"
git tag --message="" --sign "$NEW_TAG"
git push --force origin "$NEW_TAG" "$MAJOR_TAG"

echo "Version bumped to '$NEW_TAG'"
55 changes: 55 additions & 0 deletions docker-build-push/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Copyright (c) 2024 Hemi Labs, Inc.
# Use of this source code is governed by the MIT License,
# which can be found in the LICENSE file.

name: Docker Build and Push

author: Gabriel Montes

description: Build and push Docker images to Docker Hub

inputs:
context:
description: "The build context"
required: false
default: "."
dockerHubPassword:
description: "Docker Hub password"
required: true
dockerHubUsername:
description: "Docker Hub username"
required: true
images:
description: "The Docker image name"
required: true

runs:
using: composite
steps:
- uses: docker/setup-buildx-action@v3
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ inputs.images }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=ref,event=tag
type=sha,prefix=,suffix=,format=short
- uses: docker/login-action@v3
with:
password: ${{ inputs.dockerHubPassword }}
username: ${{ inputs.dockerHubUsername }}
- uses: docker/build-push-action@v6
with:
context: ${{ inputs.context }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64
provenance: true
push: true
sbom: true
tags: ${{ steps.meta.outputs.tags }}

branding:
color: blue
icon: box
49 changes: 49 additions & 0 deletions notify-deploy-to-slack/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright (c) 2024 Hemi Labs, Inc.
# Use of this source code is governed by the MIT License,
# which can be found in the LICENSE file.

name: Notify to Slack

author: Gabriel Montes

description: Send a notification to Slack using incoming webhooks

inputs:
app-name:
description: "The app being deployed"
required: true
environment:
description: "The deployment environment"
required: true
reference:
description: "Additional reference to add to the notification"
required: false
default: ""
slack-mention:
description: "The mention to include in the message"
default: <!here>
slack-webhook-url:
description: "The Slack incoming webhook URL"
required: true
status:
description: "The deployment status"
required: true

runs:
using: composite
steps:
- uses: slackapi/slack-github-action@v1
Copy link
Copy Markdown
Contributor

@joshuasing joshuasing Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a third-party action, not maintained by either GitHub or Docker, we should pin it to a commit hash in order to make it immutable.

Also, the latest version of this action is v2.1.0 (https://github.com/slackapi/slack-github-action/releases/tag/v2.1.0) - are we able to update? There is a migration guide here: https://github.com/slackapi/slack-github-action/releases/tag/v2.0.0

Suggested change
- uses: slackapi/slack-github-action@v1
- uses: slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3 # v1.27.1

https://github.com/slackapi/slack-github-action/releases/tag/v1.27.1
slackapi/slack-github-action@fcfb566

with:
payload: |
{
"text": ${{ toJSON(join(env.PAYLOAD_TEXT, '\n')) }}
}
env:
PAYLOAD_TEXT: |
${{ format('{0} Deployment of {1} to {2} {3}', inputs.slack-mention, inputs.app-name, inputs.environment, inputs.status) }}
${{ inputs.reference }}
SLACK_WEBHOOK_URL: ${{ inputs.slack-webhook-url }}

branding:
color: blue
icon: bell
38 changes: 38 additions & 0 deletions publish-to-npm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright (c) 2024 Hemi Labs, Inc.
# Use of this source code is governed by the MIT License,
# which can be found in the LICENSE file.

name: Publish to NPM

author: Gabriel Montes

description: Sets up Node, runs the prepublishOnly script and publishes the package to the NPM registry

inputs:
access:
description: Determines whether the published package should be publicly visible or restricted
required: false
default: public
token:
description: The NPM access token to use when publishing
required: true
provenance:
description: Attach provenance statements when publishing
required: false
default: "false"

runs:
using: composite
steps:
- uses: hemilabs/actions/setup-node-env@v1
- run: npm run --if-present prepublishOnly
shell: bash
- uses: JS-DevTools/npm-publish@19c28f1ef146469e409470805ea4279d47c3d35c # v3.1.1 (not audited by us)
with:
access: ${{ inputs.access }}
provenance: ${{ inputs.provenance }}
token: ${{ inputs.token }}

branding:
color: blue
icon: package
Comment thread
gndelia marked this conversation as resolved.
28 changes: 23 additions & 5 deletions setup-node-env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,39 @@

name: Setup Node

description: Setups up Node.js, restores NPM cache and installs dependencies
author: Gabriel Montes

description: Setups up Node, restores NPM cache and installs dependencies

inputs:
cache:
description: "Used to specify a package manager for caching in the default directory. Supported values: npm, yarn, pnpm."
default: npm
node-version:
description: The version of Node to install.
description: The version of Node to install
default: ""

runs:
using: composite
steps:
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
- uses: pnpm/action-setup@v4.0.0
Copy link
Copy Markdown
Contributor

@joshuasing joshuasing Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is a third-party action, not maintained by either GitHub or Docker, we should pin it to a commit hash in order to make it immutable.

Also, a minor update is available: https://github.com/pnpm/action-setup/releases/tag/v4.1.0 (changes: pnpm/action-setup@v4.0.0...v4.1.0)

Suggested change
- uses: pnpm/action-setup@v4.0.0
- uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0

https://github.com/pnpm/action-setup/releases/tag/v4.1.0
pnpm/action-setup@a7487c7

if: ${{ inputs.cache == 'pnpm' }}
- uses: actions/setup-node@v4
with:
cache: npm
cache-dependency-path: "**/package-lock.json"
cache: ${{ inputs.cache }}
cache-dependency-path: ${{ inputs.cache == 'npm' && '**/package-lock.json' || '' }}
node-version: ${{ inputs.node_version }}
node-version-file: .nvmrc
- run: npm ci
shell: bash
if: ${{ inputs.cache == 'npm' }}
- run: pnpm install --frozen-lockfile
shell: bash
if: ${{ inputs.cache == 'pnpm' }}
- run: yarn install --immutable
shell: bash
if: ${{ inputs.cache == 'yarn' }}
Comment thread
gabmontes marked this conversation as resolved.

branding:
color: blue
icon: code