Utilities
npm package publishing and Slack notifications
collabops/npm-publish@v1
On-Premise: ❌ — requires npm registry
Builds and publishes npm packages to a registry. Supports provenance.
| Input | Required | Default | Description |
|---|---|---|---|
npm-token | YES | - | npm Automation Token. $\{\{ secrets.NPM_TOKEN \}\} recommended |
access | NO | "public" | Package access level (public, restricted) |
tag | NO | "latest" | Distribution tag (latest, beta, next) |
provenance | NO | "false" | Generate provenance |
working-directory | NO | "/workspace/source" | Directory containing package.json |
Examples
Basic — publish a public package under latest
jobs:
publish:
steps:
- name: checkout
uses: "collabops/checkout@v2"
with:
repo-url: "https://<collabops-host>/<workspace>/<repository>.git"
- name: install-and-build
run: |
npm ci
npm run build
image: node:22-alpine
- name: npm-publish
uses: "collabops/npm-publish@v1"
with:
# Prefer an automation token (publish-only scope).
npm-token: ${{ secrets.NPM_TOKEN }}
Pre-release — beta tag + restricted scope
# Run only when a beta tag is pushed.
triggers:
push:
tags: ["v*-beta.*"]
jobs:
publish-beta:
steps:
- name: checkout
uses: "collabops/checkout@v2"
with:
repo-url: "https://<collabops-host>/<workspace>/<repository>.git"
- name: install-and-build
run: |
npm ci
npm run build
image: node:22-alpine
- name: npm-publish-beta
uses: "collabops/npm-publish@v1"
with:
npm-token: ${{ secrets.NPM_TOKEN }}
# Internal scoped package — never exposed publicly.
access: restricted
# Publish under the beta tag — only `npm i pkg@beta` pulls it.
tag: beta
Supply-chain security — enable provenance
jobs:
publish:
steps:
- name: checkout
uses: "collabops/checkout@v2"
with:
repo-url: "https://<collabops-host>/<workspace>/<repository>.git"
- name: install-and-build
run: |
npm ci
npm run build
image: node:22-alpine
- name: npm-publish-with-provenance
uses: "collabops/npm-publish@v1"
with:
npm-token: ${{ secrets.NPM_TOKEN }}
# Shows the 'Verified provenance' badge on npm (Sigstore-signed).
provenance: "true"
Key points — Prefer an npm automation token (publish-only scope) for npm-token. Make access explicit on scoped packages — publishes fail when it is wrong. Enable provenance: "true" whenever possible to advertise supply-chain verification on the npm page.
collabops/slack-notify@v1
On-Premise: ❌ — requires Slack connectivity
Sends notifications via a Slack Incoming Webhook.
| Input | Required | Default | Description |
|---|---|---|---|
webhook-url | YES | - | Slack Incoming Webhook URL. $\{\{ secrets.SLACK_WEBHOOK \}\} recommended |
payload | NO | "" | Custom JSON payload (other fields are ignored when set) |
message | NO | "" | Notification message text (required when payload is not used) |
title | NO | "" | Message title |
color | NO | "good" | Message color (good, warning, danger, or hex) |
icon-emoji | NO | "" | Bot icon emoji (e.g., :rocket:) |
username | NO | "" | Bot name override |
channel | NO | "" | Target channel (overrides webhook default channel) |
Examples
Simple success notification
# Success notifications live in a separate Job with a Job-level if: "success()".
jobs:
deploy:
steps:
- name: deploy
run: ./deploy.sh
image: alpine:3.20
notify-success:
needs: [deploy]
if: "success()"
steps:
- name: notify
uses: "collabops/slack-notify@v1"
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
title: "Deploy success"
message: "Deployed sha ${{ collabops.sha }}"
color: good
channel: "#deploys"
Notify on failure only
# Failure notifications live in a separate Job with if: "failure()". Step-level if is unsupported.
jobs:
deploy:
steps:
- name: do-deploy
run: ./deploy.sh
image: alpine:3.20
notify-failure:
needs: [deploy]
if: "failure()"
steps:
- name: notify
uses: "collabops/slack-notify@v1"
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
title: "Deploy failed"
message: "${{ collabops.actor }}'s deploy of ${{ collabops.sha }} failed — check the logs"
color: danger
channel: "#alerts"
Advanced — Block Kit payload
jobs:
notify:
steps:
- name: rich-payload
uses: "collabops/slack-notify@v1"
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
# When payload is set it overrides message/title/color.
# Pass the JSON literally, preserving newlines.
payload: |
{
"blocks": [
{ "type": "header", "text": { "type": "plain_text", "text": "Release ${{ collabops.ref_name }}" } },
{ "type": "section", "text": { "type": "mrkdwn", "text": "*sha:* `${{ collabops.sha }}`" } }
]
}
Key points — webhook-url is a per-channel Incoming Webhook secret. Step-level if is unsupported, so route conditional notifications through separate Jobs with a Job-level if: "success()" or if: "failure()". For rich messages use payload with a full Block Kit JSON — it takes precedence over message/title/color.