Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
8a3273f
Merge branch 'production'
nozols Sep 18, 2026
e6846c7
Merge branch 'production'
nozols Sep 18, 2026
b9a8bf2
fix: Share one random-start TSN counter per node
RobinBol Oct 22, 2026
514668f
fix: Resolve command when response arrives before send failure
RobinBol Oct 22, 2026
f73fd2b
fix: Only skip responses for global Default Response frames
RobinBol Oct 22, 2026
59382dc
fix: Match pending responses by command, not only by TSN
RobinBol Oct 22, 2026
c5a978e
fix: Send UNSUP_COMMAND and UNSUPPORTED_CLUSTER in Default Response
RobinBol Oct 22, 2026
763a746
Emit the transaction sequence number with attribute reports
TedTolboom Oct 22, 2026
b36d342
fix: Log frames that share a pending TSN but are not its response
RobinBol Oct 22, 2026
717570a
docs: Document optional nextSeqNr on EndpointInput
RobinBol Oct 22, 2026
63cdfed
test: Accept any error status in the 0x0B Default Response test
RobinBol Oct 22, 2026
8b78b59
fix: Skip default responses to broadcast frames
RobinBol Oct 22, 2026
09c8070
fix: Answer unicast frames to the broadcast endpoint
RobinBol Oct 22, 2026
709c921
fix(alarms): Declare Get Alarm Response for getAlarm
RobinBol Oct 22, 2026
c2c1cbb
fix: Keep resolving undeclared replies on a cluster-specific frame
RobinBol Oct 22, 2026
2714b64
fix: Treat a declared response without id as the command id
RobinBol Oct 22, 2026
260573c
refactor: Spell out the pending response match in handleFrame
RobinBol Oct 22, 2026
ba60919
refactor: Store a pending transaction as a plain object
RobinBol Oct 22, 2026
16811f3
test: Cover the frame type and Default Response command checks
RobinBol Oct 22, 2026
b46e52b
Merge pull request #235 from athombv/fix/shared-tsn-per-node
RobinBol Oct 22, 2026
7d41dae
Merge pull request #236 from athombv/fix/default-response-check-frame…
RobinBol Oct 22, 2026
3628a18
Merge pull request #239 from athombv/fix/zcl-unsupported-status-codes
RobinBol Oct 22, 2026
c876c6a
Merge pull request #238 from athombv/fix/no-default-response-to-broad…
RobinBol Oct 22, 2026
935779b
Merge remote-tracking branch 'origin/master' into fix/match-responses…
RobinBol Oct 22, 2026
27f281c
Merge pull request #237 from athombv/fix/match-responses-by-command
RobinBol Oct 22, 2026
8797f22
fix: Only expose the transaction sequence number with attribute reports
RobinBol Oct 22, 2026
9a26848
Merge pull request #240 from TedTolboom/feature/report-trx-sequence-n…
RobinBol Oct 22, 2026
c13e563
build(deps): Update dev dependencies to clear audit findings
RobinBol Oct 22, 2026
1a31743
Merge pull request #241 from athombv/chore/update-dependencies
RobinBol Oct 22, 2026
2885ed1
chore: Resolve the @athombv scope from npmjs
RobinBol Oct 22, 2026
969a2fd
Merge pull request #242 from athombv/chore/pin-athombv-scope-to-npmjs
RobinBol Oct 22, 2026
8ecdad1
chore: run generate-types with node's native type stripping
RobinBol Oct 22, 2026
658edc3
Merge pull request #243 from athombv/chore/native-type-stripping
RobinBol Oct 23, 2026
bb1a6a1
chore: migrate to eslint 10 flat config (#244)
RobinBol Oct 23, 2026
d542043
chore: Add Prettier
RobinBol Oct 23, 2026
3af13a5
refactor: Move the M/O annotations above the attribute key
RobinBol Oct 23, 2026
692f0e3
chore: Apply Prettier
RobinBol Oct 23, 2026
545233d
docs: Record where the M/O annotation goes, and lowercase hex
RobinBol Oct 23, 2026
b1fd714
ci: Run the Prettier check in the Lint workflow
RobinBol Oct 23, 2026
5b26951
refactor: Use the node: prefix for core imports in lib
RobinBol Oct 23, 2026
da91f20
Merge pull request #245 from athombv/chore/prettier
RobinBol Oct 23, 2026
96d21d5
chore: Drop the docs server in favor of opening the files
RobinBol Oct 23, 2026
d01cecc
chore: Replace mocha and sinon with node:test
RobinBol Oct 23, 2026
5bd4b42
refactor: Use the node: prefix for the assert import in tests
RobinBol Oct 23, 2026
f9c8778
ci: Pin development and CI to Node 22
RobinBol Oct 23, 2026
187ec5e
ci: Gate the testing branch, cache npm, update the actions
RobinBol Oct 23, 2026
a88b95e
ci: Keep publishing working on Node 22 and gate it on the checks
RobinBol Oct 23, 2026
ae2a43d
ci: Validate before building the docs in the deploy job
RobinBol Oct 23, 2026
187ca5e
Merge pull request #246 from athombv/chore/docs-preview-without-serve
RobinBol Oct 23, 2026
48eaef4
Merge pull request #247 from athombv/chore/node-test
RobinBol Oct 23, 2026
bd01c5b
Merge pull request #250 from athombv/chore/workflow-hygiene
RobinBol Oct 23, 2026
a042b77
docs: List the format and type commands, drop a stale npmignore note
RobinBol Oct 23, 2026
4b642ca
Merge pull request #251 from athombv/docs/tidy-tooling-notes
RobinBol Oct 23, 2026
1d43400
ci: Create a GitHub release with grouped notes on publish
RobinBol Oct 23, 2026
276dcb4
ci: Drop the testing branch and beta publishing
RobinBol Oct 23, 2026
ff36f24
ci: Fail the release step when generating the notes fails
RobinBol Oct 23, 2026
b85552d
ci: Relabel pull requests when the base branch or the prefix changes
RobinBol Oct 23, 2026
224af3c
ci: Start the first release notes from the last version on npm
RobinBol Oct 23, 2026
537e4c1
ci: Label pull requests from their current state, one run at a time
RobinBol Oct 23, 2026
ad97909
docs: Explain how to release and how the release notes come about
RobinBol Oct 23, 2026
0fe3fce
docs: Correct the type generation section of the README
RobinBol Oct 23, 2026
5dc68a5
ci: Derive the release labels from the title and base branch alone
RobinBol Oct 23, 2026
a90fb76
Merge pull request #252 from athombv/chore/release-notes
RobinBol Oct 23, 2026
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
2 changes: 0 additions & 2 deletions .eslintignore

This file was deleted.

3 changes: 0 additions & 3 deletions .eslintrc.json

This file was deleted.

23 changes: 23 additions & 0 deletions .github/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Categories for the notes GitHub generates when the deploy workflow creates a release.
# The labels are set from the conventional-commit prefix of the pull request title by
# .github/workflows/label-pr.yml.
changelog:
exclude:
labels:
- internal
- release
categories:
- title: Breaking changes
labels:
- breaking
- title: New features
labels:
- feature
- title: Fixes
labels:
- fix
# Titles without a conventional prefix, typically outside contributions. Retitle the pull
# request to move it.
- title: Other changes
labels:
- '*'
90 changes: 60 additions & 30 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
name: Deploy

# About this workflow:
# It is triggered on push events to branches production and testing. Then it performs a checkout of the current repo
# and sets up a node environment (v12). Following, it will run `npm ci` to build the package. Next, it will look at your
# It is triggered on push events to the production branch. Then it performs a checkout of the current repo
# and sets up a node environment (see .nvmrc). Following, it will run `npm ci` to build the package. Next, it will look at your
# commit message, if it includes '#patch', '#minor', or '#major' it will bump the package version accordingly.
# Finally, the `npm publish` command will be run, when on branch testing it will run `npm publish --tag beta` to publish
# it under the beta flag on npm. Note: if no '#patch', '#minor', or '#major' flag is present in the latest commit
# AND the package version is not bumped manually the publish step will fail because we can not publish to an existing
# version.
# Finally, the `npm publish` command will be run. Note: if no '#patch', '#minor', or '#major' flag is present in the latest
# commit AND the package version is not bumped manually the publish step will fail because we can not publish to an
# existing version.
# Once npm has accepted the version, a GitHub release with generated notes is created.
# See .github/release.yml for how the notes are grouped.

# GitHub repo configuration:
# 1. Go to Manage access and add 'Github Actions' team with role: admin.
Expand All @@ -16,13 +17,12 @@ name: Deploy

# Note: make sure to commit package-lock.json, this is needed for `npm ci`.

# Defines the trigger for this action, in general you want it to run when pushing to production | testing. For more
# Defines the trigger for this action, in general you want it to run when pushing to production. For more
# information see: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#about-workflow-events)
on:
push:
branches:
- production
- testing
workflow_dispatch:
inputs:
versionBumpType:
Expand All @@ -33,10 +33,10 @@ jobs:
deploy_to_npm:
name: Version Bump & Deploy to NPM

# Only run this job if initiator is not the Homey Github Actions Bot to prevent loops and check if if a version bump is provided and current branch is production or testing
# Only run this job if initiator is not the Homey Github Actions Bot to prevent loops and check if a version bump is provided and current branch is production
if: github.actor != 'homey-bot'
&& (github.ref == 'refs/heads/production' || github.ref == 'refs/heads/testing')
&& (github.event.inputs.versionBumpType == 'patch' || github.event.inputs.versionBumpType == 'minor' || github.event.inputs.versionBumpType == 'major' || contains(github.event.head_commit.message, '#patch') || contains(github.event.head_commit.message, '#minor') || contains(github.event.head_commit.message, '#major'))
&& github.ref == 'refs/heads/production'
&& (github.event.inputs.versionBumpType == 'patch' || github.event.inputs.versionBumpType == 'minor' || github.event.inputs.versionBumpType == 'major' || contains(github.event.head_commit.message, '#patch') || contains(github.event.head_commit.message, '#minor') || contains(github.event.head_commit.message, '#major'))

runs-on: ubuntu-latest

Expand All @@ -47,13 +47,14 @@ jobs:
id-token: write

steps:

# Checks out the current repository.
- name: Checkout git repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
# The token below is only necessary if you want to push the version bump to a protected branch
token: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
# Full history and tags, so the release step can find the previous tag.
fetch-depth: 0

# Set git config to reflect Homey Github Actions Bot user
- name: Set up HomeyGithubActionsBot git user
Expand All @@ -64,16 +65,32 @@ jobs:
# Configures a Node.js environment pointed at the public npm registry so
# `npm publish` uses OIDC against npmjs.org.
- name: Set up Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: 'npm'
registry-url: https://registry.npmjs.org

# Run `npm ci && npm run build` to re-create your local environment (make sure to commit your - package-lock.json!).
- name: Build
# OIDC trusted publishing needs npm 11.5.1 or newer. Node 22 bundles npm 10,
# and setup-node installs whatever npm ships with the Node version.
- name: Upgrade npm for trusted publishing
run: npm install -g npm@^11.5.1

# Run `npm ci` to re-create your local environment (make sure to commit your - package-lock.json!).
- name: Install
run: npm ci

# Nothing below this point runs if the package does not lint, format or test
# cleanly, so nothing reaches npm that was never checked. Ahead of the docs build,
# which is the slowest step here.
- name: Validate
run: |
npm ci
npm run build
npm run lint
npm run format:check
npm test

- name: Build
run: npm run build

- name: Version bump patch
if: github.event.inputs.versionBumpType == 'patch' || contains(github.event.head_commit.message, '#patch') && !contains(github.event.head_commit.message, '#minor') && !contains(github.event.head_commit.message, '#major')
Expand All @@ -96,20 +113,33 @@ jobs:
git pull
git push --follow-tags

# Publish when this action is running on branch production.
# No NPM_AUTH_TOKEN: auth is brokered via OIDC against the npm
# Trusted Publisher configured on the package on npmjs.com.
- name: Publish
if: github.ref == 'refs/heads/production'
run: npm publish --provenance

# After the publish, and starting from the previous release rather than the previous tag,
# because a publish that fails after the version bump leaves a tag without an npm version
# behind (v2.7.0, v3.1.0). Until the first release exists, the start is the last version npm
# actually has, for the same reason. If this step fails, create the release by hand: a rerun
# would bump again.
- name: Create GitHub release
# Explicit, because only then does Actions add pipefail: without it a failing gh api still
# feeds the Node filter an empty input, and an empty release gets published.
shell: bash
env:
GH_TOKEN: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
run: |
npm publish --provenance
VERSION="$(node -p "require('./package.json').version")"
echo package_version=${VERSION} >> $GITHUB_ENV

# Publish to beta when this action is running on branch testing.
- name: Publish to beta
if: github.ref == 'refs/heads/testing'
run: |
npm publish --provenance --tag beta
VERSION="$(node -p "require('./package.json').version")@beta"
echo package_version=${VERSION} >> $GITHUB_ENV
TAG="v$VERSION"
if ! PREVIOUS_TAG="$(gh release view --json tagName -q .tagName)"; then
PREVIOUS_TAG="v$(npm view "zigbee-clusters@<$VERSION" version --json \
| node -p "[].concat(JSON.parse(require('node:fs').readFileSync(0, 'utf8'))).at(-1)")"
fi
# The notes list each pull request title as is. Drop its conventional-commit prefix, which the
# category heading above it already says.
gh api "repos/$GITHUB_REPOSITORY/releases/generate-notes" \
-f tag_name="$TAG" -f previous_tag_name="$PREVIOUS_TAG" --jq .body \
| node -e "process.stdout.write(require('node:fs').readFileSync(0, 'utf8').replace(/^\* \w+(\([^)]*\))?!?: (.)/gm, (_, _scope, first) => '* ' + first.toUpperCase()))" \
> release-notes.md
gh release create "$TAG" --verify-tag --title "$TAG" --notes-file release-notes.md
43 changes: 21 additions & 22 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,33 @@ name: Deploy Documentation To GitHub Pages

# Note: make sure to commit package-lock.json, this is needed for `npm ci`.

# Note: add `.github` to .npmignore

on:
push:
branches: [ production ]
branches: [production]
workflow_dispatch:

jobs:
deploy:
name: Build & Deploy to GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc

# Build
- name: Build
run: |
npm ci
npm run build

# Deploy
- name: Deploy To GitHub Pages
uses: peaceiris/actions-gh-pages@v3.8.0
with:
personal_token: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
publish_dir: ./build
- uses: actions/checkout@v7

- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: 'npm'

# Build
- name: Build
run: |
npm ci
npm run build

# Deploy
- name: Deploy To GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}
publish_dir: ./build
19 changes: 9 additions & 10 deletions .github/workflows/generate-types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ on:
push:
branches-ignore:
- production
- testing
paths:
- "lib/clusters/**/*.js"
- "scripts/generate-types.mts"
- "scripts/template.d.ts.txt"
- "index.js"
- "lib/Cluster.js"
- "lib/constants.js"
- 'lib/clusters/**/*.js'
- 'scripts/generate-types.mts'
- 'scripts/template.d.ts.txt'
- 'index.js'
- 'lib/Cluster.js'
- 'lib/constants.js'
workflow_dispatch:

jobs:
Expand All @@ -23,16 +22,16 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
ref: ${{ github.ref_name }}
token: ${{ secrets.HOMEY_GITHUB_ACTIONS_BOT_PERSONAL_ACCESS_TOKEN }}

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: "npm"
cache: 'npm'

- name: Install dependencies
run: npm ci
Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/label-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: Label pull request

# Labels each pull request from the conventional-commit prefix of its title, so the release
# notes can sort it (see .github/release.yml). Re-runs when the title or base branch is edited.
# The five labels below follow the title alone: to move a pull request, retitle it.
#
# pull_request_target so pull requests from forks get a token that can label. This is safe
# because the job never checks out or runs code from the pull request.
on:
pull_request_target:
types: [opened, edited, reopened]

permissions:
pull-requests: write

# One run at a time per pull request, so two quick edits cannot each add a label the other
# should have removed.
concurrency:
group: label-pr-${{ github.event.pull_request.number }}

jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v9
with:
script: |
const MANAGED_LABELS = ['breaking', 'feature', 'fix', 'internal', 'release'];
const INTERNAL_TYPES = ['build', 'chore', 'ci', 'docs', 'refactor', 'style', 'test'];

function labelFor(title, baseRef) {
if (baseRef === 'production') return 'release';
const match = /^(\w+)(?:\([^)]*\))?(!)?:/.exec(title);
if (!match) return null;
const [, type, breaking] = match;
if (breaking) return 'breaking';
if (type === 'feat') return 'feature';
if (type === 'fix' || type === 'perf') return 'fix';
if (INTERNAL_TYPES.includes(type)) return 'internal';
return null;
}

const { action, changes = {} } = context.payload;
// The label depends on the title and the base branch; other edits change nothing.
if (action === 'edited' && !changes.title && !changes.base) return;

// The payload is a snapshot from when the event fired. Read the pull request as it is
// now, so labels an earlier run added are seen and the latest title wins.
const { data: pullRequest } = await github.rest.pulls.get({
...context.repo,
pull_number: context.payload.pull_request.number,
});

// The managed labels are a function of the current title and base only, so whichever
// runs happen to execute, the last one leaves them right. No prefix means none of them.
const wanted = labelFor(pullRequest.title, pullRequest.base.ref);
const current = pullRequest.labels.map(label => label.name);
const issue = { ...context.repo, issue_number: pullRequest.number };

for (const name of current) {
if (MANAGED_LABELS.includes(name) && name !== wanted) {
await github.rest.issues.removeLabel({ ...issue, name });
}
}
if (wanted && !current.includes(wanted)) {
await github.rest.issues.addLabels({ ...issue, labels: [wanted] });
}
8 changes: 5 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,19 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:

# Checks out the current repository.
- uses: actions/checkout@v4
- uses: actions/checkout@v7

# Configures a Node.js environment.
- uses: actions/setup-node@v4
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: 'npm'

# Run `npm ci` to re-create your local environment (make sure to commit your package-lock.json!).
# Finally run `npm run lint` (make sure you have defined a lint command in package.json e.g. "lint": "eslint .").
- run: npm ci

- run: npm run lint

- run: npm run format:check
5 changes: 3 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ jobs:

steps:
# Checks out the current repository.
- uses: actions/checkout@v4
- uses: actions/checkout@v7

# Configures a Node.js environment.
- uses: actions/setup-node@v4
- uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: 'npm'

# Run `npm ci` to re-create your local environment (make sure to commit your package-lock.json!).
# Finally run `npm test` (make sure you have defined a proper test command in package.json).
Expand Down
3 changes: 3 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Both @athombv packages used here are published to npmjs.org. Without this, a
# machine that points the @athombv scope at GitHub Packages fails to install them.
@athombv:registry=https://registry.npmjs.org/
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24
22
Loading
Loading