Skip to content

Commit 3679301

Browse files
authored
Add configurable button actions and Lua HTTP support (#16)
* feat(lua): add action HTTP runtime * feat(executor): bridge Lua button actions * feat(instance): dispatch button actions * feat(ui): configure button press actions * build: upgrade Go and dependencies * ci: add dependency security scans * fix: keep Stream Deck event loop responsive Run press actions outside the synchronous SDK reader and separate lifecycle cancellation from polling restarts so settings updates do not cancel active actions. * ci: repair checks and add test package * ci: install Codecov prerequisites * fix: harden API request handling * fix: contain Stream Deck handler panics * feat: docs * chore: add repository code owners
1 parent 2465acf commit 3679301

33 files changed

Lines changed: 2322 additions & 374 deletions

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @ft-t/devs
Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
on:
22
pull_request:
3+
workflow_dispatch:
34
push:
45
branches:
56
- master
@@ -9,18 +10,18 @@ on:
910
jobs:
1011
test:
1112
runs-on: ubuntu-latest
12-
container: golang:1.25-alpine
13+
container: golang:1.26.5-alpine
1314
env:
1415
ENVIRONMENT: ci
1516
steps:
16-
- uses: actions/checkout@v4
17-
- run: apk update && apk add curl openssl git openssh-client build-base && mkdir -p /root/.ssh
18-
- run: wget -O /usr/bin/mockgen https://github.com/skynet2/mock/releases/latest/download/mockgen && chmod 777 /usr/bin/mockgen
17+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
18+
- run: apk update && apk add bash curl gnupg openssl git openssh-client build-base && mkdir -p /root/.ssh
19+
- run: go install github.com/golang/mock/mockgen@v1.6.0
1920
- run: make generate
2021
- run: go test -json -coverprofile=/root/coverage_temp.txt -covermode=atomic ./... > /root/test.json
2122
- run: cat /root/coverage_temp.txt | grep -v "_mock.go" | grep -v "_mocks.go" | grep -v "_mocks_test.go" | grep -v "_mock_test.go" > /root/coverage.txt || true
2223
- name: Upload coverage report
23-
uses: codecov/codecov-action@v3
24+
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
2425
with:
2526
token: ${{ secrets.CODECOV_TOKEN }}
2627
files: /root/coverage.txt
@@ -29,19 +30,58 @@ jobs:
2930
if: always()
3031
- run: wget https://github.com/mfridman/tparse/releases/latest/download/tparse_linux_x86_64 -O tparse && chmod 777 tparse && ./tparse -all -file=/root/test.json
3132
if: always()
32-
- uses: guyarb/golang-test-annotations@v0.7.0
33+
- uses: guyarb/golang-test-annotations@96fc379b171c49932041d6c789e73331a7bdeec1 # v0.9.0
3334
if: always()
3435
with:
3536
test-results: /root/test.json
3637
lint:
3738
runs-on: ubuntu-latest
38-
container: golang:1.25-alpine
39+
container: golang:1.26.5-alpine
3940
env:
4041
ENVIRONMENT: ci
4142
steps:
42-
- uses: actions/checkout@v4
43-
- uses: golangci/golangci-lint-action@v6.1.1
43+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
44+
- uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
4445
if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/qa' && github.ref != 'refs/heads/uat'
4546
with:
46-
version: latest
47+
version: v2.12.2
4748
args: --timeout=5m --tests=false ./...
49+
trivy:
50+
runs-on: ubuntu-latest
51+
steps:
52+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
53+
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
54+
with:
55+
scan-type: fs
56+
scan-ref: .
57+
format: table
58+
exit-code: '1'
59+
ignore-unfixed: true
60+
severity: HIGH,CRITICAL
61+
govulncheck:
62+
runs-on: ubuntu-latest
63+
container: golang:1.26.5-alpine
64+
steps:
65+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
66+
- run: apk update && apk add git make
67+
- run: go install golang.org/x/vuln/cmd/govulncheck@latest
68+
- run: make security-govulncheck
69+
package:
70+
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
71+
runs-on: ubuntu-latest
72+
env:
73+
TARGET_VERSION: 1.0.${{ github.run_number }}.0
74+
steps:
75+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
76+
- name: Set version in manifest
77+
run: jq --arg ver "$TARGET_VERSION" '.Version = $ver' ./resources/manifest.json > temp.json && mv temp.json ./resources/manifest.json
78+
- name: Build test package
79+
run: |
80+
docker build -t apimonkey-package .
81+
docker run --rm -v "$PWD/tmpdist:/tmpdist" apimonkey-package sh -c "cp /dist/com.ftt.apimonkey.sdPlugin.zip /tmpdist/com.ftt.apimonkey.sdPlugin.zip"
82+
- name: Upload test package
83+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
84+
with:
85+
path: tmpdist/com.ftt.apimonkey.sdPlugin.zip
86+
archive: false
87+
if-no-files-found: error

.github/workflows/release.yaml

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,26 @@ jobs:
1818
run: echo "semVersion=$MAJOR_VERSION.0.${{ github.run_number }}" >> "$GITHUB_OUTPUT"
1919
ci:
2020
runs-on: ubuntu-latest
21+
permissions:
22+
contents: write
2123
needs:
2224
- version
2325
env:
2426
TARGET_VERSION: ${{needs.version.outputs.versionOut}}
2527
SEM_VERSION: ${{needs.version.outputs.versionSemVerOut}}
2628
steps:
2729
- run: sudo apt-get update && sudo apt-get install -y jq
28-
- uses: actions/checkout@v4
30+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
2931
- name: Set version in manifest
3032
run: jq --arg ver "$TARGET_VERSION" '.Version = $ver' ./resources/manifest.json > temp.json && mv temp.json ./resources/manifest.json
3133
- run: docker build -t temp .
32-
- run: docker run -v $(pwd)/tmpdist:/tmpdist temp sh -c "cp /dist/com.ftt.apimonkey.sdPlugin.zip /tmpdist/com.ftt.apimonkey.sdPlugin.zip"
34+
- run: docker run --rm -v "$PWD/tmpdist:/tmpdist" temp sh -c "cp /dist/com.ftt.apimonkey.sdPlugin.zip /tmpdist/com.ftt.apimonkey.sdPlugin.zip"
3335
- name: release
34-
uses: actions/create-release@v1
35-
id: create_release
36+
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
3637
with:
3738
draft: false
3839
prerelease: false
39-
release_name: ${{ env.TARGET_VERSION }}
40+
name: ${{ env.TARGET_VERSION }}
4041
tag_name: ${{ env.SEM_VERSION }}
41-
env:
42-
GITHUB_TOKEN: ${{ github.token }}
43-
- name: upload windows artifact
44-
uses: actions/upload-release-asset@v1
45-
env:
46-
GITHUB_TOKEN: ${{ github.token }}
47-
with:
48-
upload_url: ${{ steps.create_release.outputs.upload_url }}
49-
asset_path: tmpdist/com.ftt.apimonkey.sdPlugin.zip
50-
asset_name: com.ftt.apimonkey.sdPlugin.zip
51-
asset_content_type: application/octet-stream
42+
files: tmpdist/com.ftt.apimonkey.sdPlugin.zip
43+
fail_on_unmatched_files: true

AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# AGENTS.md
2+
3+
Read and follow [CLAUDE.md](CLAUDE.md) before making any changes.

CLAUDE.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# CLAUDE.md
2+
3+
## Project
4+
5+
API Monkey is a Go 1.26 Stream Deck plugin. It sends configured HTTP requests, processes responses, and updates Stream Deck keys. Releases package Windows x64 and macOS arm64 binaries with `resources/` into `com.ftt.apimonkey.sdPlugin.zip`.
6+
7+
Read [README.md](README.md), [docs/usage.md](docs/usage.md), and [docs/lua.md](docs/lua.md) before changing user-visible behavior.
8+
9+
## Repository map
10+
11+
- `main.go`: application wiring and Stream Deck event handlers.
12+
- `pkg/common`: saved configuration and validation.
13+
- `pkg/executor`: request templates, HTTP execution, JSON selection, and response Lua dispatch.
14+
- `pkg/instance`: per-key lifecycle, polling, actions, response mapping, and Stream Deck updates.
15+
- `pkg/scripts`: response Lua, action Lua, JSON module setup, and action HTTP API.
16+
- `pkg/sdk`: Stream Deck SDK adapter.
17+
- `pkg/utils`: browser, file, and Go template helpers.
18+
- `resources/manifest.json`: plugin metadata and supported platforms.
19+
- `resources/pi/pi.html`: Property Inspector fields and saved settings.
20+
- `docs/usage.md`: canonical user-facing feature and configuration guide.
21+
- `docs/lua.md`: canonical Lua scripting contract.
22+
23+
## Required workflow
24+
25+
- Run `gopls go_workspace` before working in this Go workspace.
26+
- Read a package's `interfaces.go` before modifying that package.
27+
- After first reading a Go file, inspect its `gopls go_file_context`.
28+
- Use `gopls` for Go symbols, references, renames, diagnostics, and package APIs.
29+
- Use Codebase Memory for architecture, call chains, change impact, and structural discovery.
30+
- Prefer repository Makefile targets over direct tool commands when a matching target exists.
31+
- Keep changes inside requested scope. Ask before changing public APIs, schemas, dependencies, or unrelated packages.
32+
- Do not delete or rename existing assets, configuration, or fixtures to fix a failure.
33+
34+
## Code rules
35+
36+
- Keep code explicit, small, and boring. Avoid unrelated refactors.
37+
- Public blocking or I/O methods accept `context.Context` first.
38+
- Define minimal interfaces where consumed.
39+
- Never pass dependencies as `nil` unless a constructor explicitly documents a nil sentinel.
40+
- Use `github.com/golang/mock/gomock`. Generate mocks; never hand-edit generated mock files.
41+
- Use the logger carried by `context.Context` through `zerolog.Ctx(ctx)`.
42+
- Preserve error identity with wrapping. Use `errors.Is` and `errors.As`; never compare error strings.
43+
- Handle every returned error. Log only documented best-effort cleanup failures.
44+
- Tests must not perform real network, filesystem, clock, or random I/O. Database tests are the only real-I/O exception.
45+
- Keep success and failure test tables separate. Do not branch on expected outcomes inside tests.
46+
47+
## Commands
48+
49+
```bash
50+
make generate
51+
make lint
52+
go test -p 1 -timeout 60s ./...
53+
go build ./...
54+
```
55+
56+
Run `make generate` after interface changes. Before declaring work complete, `make lint`, tests for modified packages with `-p 1 -timeout 60s`, and `go build ./...` must pass.
57+
58+
`make build-apimonkey-windows` builds a Windows development package in `dist/`. `Dockerfile` is the cross-platform release packaging source of truth.
59+
60+
## Lua changes
61+
62+
Response and action Lua are separate contracts:
63+
64+
- Response Lua: `Lua.Execute`, globals `ResponseBody` and `ResponseStatusCode`.
65+
- Action Lua: `Lua.ExecuteAction`, globals `ButtonContextID`, `ButtonConfig`, and `http`.
66+
67+
When changing Lua behavior:
68+
69+
1. Read `pkg/scripts/interfaces.go` and `pkg/scripts/lua.go` with gopls context.
70+
2. Update `pkg/scripts/lua_test.go` without real HTTP calls.
71+
3. Update [docs/lua.md](docs/lua.md) in the same change.
72+
4. Update [docs/usage.md](docs/usage.md) when configuration or visible behavior changes.
73+
5. Update `README.md` only when the high-level feature list, install steps, platform support, or quick start changes.
74+
75+
## Documentation rules
76+
77+
- Treat current code, tests, Property Inspector, manifest, and release workflow as source of truth.
78+
- Keep README concise; link to detailed guides instead of duplicating them.
79+
- Put configuration and end-user examples in `docs/usage.md`.
80+
- Put all Lua globals, APIs, return rules, errors, and Lua examples in `docs/lua.md`.
81+
- Keep examples executable against the documented contract. Never document planned behavior as available.
82+
- Preserve existing images under `docs/` unless replacement is explicitly requested.
83+
84+
## Git
85+
86+
- Do not commit or push to `master`, `main`, `qa`, `uat`, or `Release/*` without explicit approval.
87+
- Sign every commit with `git commit -S`. Never bypass signing.
88+
- Do not add an AI co-author.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.24-bookworm
1+
FROM golang:1.26.5-bookworm
22
RUN apt-get update && apt-get install zip git -y
33
ADD . /src
44
WORKDIR /src

Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,13 @@ lint:
2222

2323
.PHONY: generate
2424
generate:
25-
go generate ./...
25+
go generate ./...
26+
27+
.PHONY: security security-trivy security-govulncheck
28+
security: security-trivy security-govulncheck
29+
30+
security-trivy:
31+
trivy fs --format table --exit-code 1 --ignore-unfixed --severity HIGH,CRITICAL .
32+
33+
security-govulncheck:
34+
govulncheck ./...

0 commit comments

Comments
 (0)