Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a679a02
feat(lint): add render builder validation and helper-backed type dete…
moshloop Jun 2, 2026
c7d341e
feat(task): Add task registry with run listing, filtering, and drill-…
moshloop Jun 2, 2026
0d6c281
feat(api,openapi,lint): Add optional ID support for entity actions an…
moshloop Jun 2, 2026
848e66f
chore: update docs
moshloop Jun 2, 2026
04c0fdf
feat(task): Add OnBeforeGC hook and RunsRaw for GC lifecycle control
moshloop Jun 2, 2026
91bd274
ci(workflows): consolidate CI/CD workflows into gavel and dist
moshloop Jun 2, 2026
147d9e8
feat(metrics): add timeseries metrics store with in-memory and valkey…
moshloop Jun 2, 2026
4cded8b
refactor(timeseries): replace oipa references with generic app prefix
moshloop Jun 2, 2026
fe92ea2
build(cache): Replace go-sqlite3 with modernc.org/sqlite for CGO-free…
moshloop Jun 2, 2026
20357b0
docs(cache): clarify SQLite driver selection rationale in comments
moshloop Jun 2, 2026
346aa64
ci(workflows): split gavel into separate test and lint jobs with node…
moshloop Jun 2, 2026
5f27eb9
ci(workflows): run gavel lint as raw step to avoid --show-passed inje…
moshloop Jun 2, 2026
7deaa1a
fix(rpc): serve ExecutionResponse envelope for structured wire formats
moshloop Jun 2, 2026
b33a67f
fix(examples): tag standalone demos with //go:build ignore
moshloop Jun 2, 2026
3ef4ea9
chore(examples): tidy go.mod after tagging demos as build-ignore
moshloop Jun 2, 2026
00e2f87
build(webapp): Add placeholder index.html for go:embed resolution in CI
moshloop Jun 3, 2026
d3ad0ea
fix(task): WaitFor returns result after in-closure terminal SetStatus
moshloop Jun 3, 2026
cec918f
feat(entity,command,rpc): add context-aware data functions for reques…
moshloop Jun 3, 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
45 changes: 45 additions & 0 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Dist

on:
push:
branches: [main, master, develop]
workflow_dispatch:

jobs:
# Rebuild the embedded task-ui bundle from source and commit it back when it
# changed. dist/taskui.js is gitignored build output that task/ui/assets.go
# embeds via `//go:embed`, so it must be kept in sync with task/ui/src.
# Only runs on push (a real branch to push to); the commit is marked
# [skip ci] to avoid re-triggering this workflow.
task-ui:
name: Rebuild task-ui bundle
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Build and commit task-ui bundle
env:
GH_TOKEN: ${{ secrets.FLANKBOT }}
run: |
make task-ui
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -f task/ui/dist/taskui.js
if ! git diff --cached --quiet; then
git commit -m "chore(embed): rebuild task-ui bundle [skip ci]"
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git"
git push origin HEAD:${{ github.ref_name }}

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate or quote the branch reference to prevent injection.

github.ref_name is expanded into the git push command without validation or quoting. Although this workflow is restricted to specific branches, branch names containing shell metacharacters could lead to command injection if branch protections are misconfigured.

🛡️ Proposed fix to quote the variable
           git remote set-url origin "https://x-access-token:${GH_TOKEN}`@github.com/`${{ github.repository }}.git"
-          git push origin HEAD:${{ github.ref_name }}
+          git push origin "HEAD:${{ github.ref_name }}"

Alternatively, validate that ref_name matches expected branches:

           git remote set-url origin "https://x-access-token:${GH_TOKEN}`@github.com/`${{ github.repository }}.git"
+          case "${{ github.ref_name }}" in
+            main|master|develop) ;;
+            *) echo "Unexpected branch: ${{ github.ref_name }}"; exit 1 ;;
+          esac
           git push origin HEAD:${{ github.ref_name }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
git push origin HEAD:${{ github.ref_name }}
git push origin "HEAD:${{ github.ref_name }}"
🧰 Tools
🪛 zizmor (1.25.2)

[error] 42-42: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/dist.yml at line 42, The git push invocation uses an
unquoted expansion of github.ref_name ("git push origin HEAD:${{ github.ref_name
}}"), which risks shell injection; update the workflow to either validate
github.ref_name against allowed branch names (e.g., match expected branches in a
conditional) or quote/escape the variable expansion so it is treated as a single
safe ref (e.g., ensure the push ref is wrapped in quotes or passed as a single
argument), and update the step that runs the push so it references the
validated/quoted value instead of the raw github.ref_name.

else
echo "task-ui bundle unchanged"
fi
98 changes: 98 additions & 0 deletions .github/workflows/gavel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: CI

on:
push:
branches: [main, master, develop]
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:

env:
GO_VERSION: "1.26"

jobs:
test:
name: Test
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"

- name: Gavel test
uses: flanksource/gavel@main
with:
args: test
comment-header: gavel-test
artifact-name: gavel-test-results

lint:
name: Lint
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"

# The gavel action always injects `--show-passed`, which `gavel lint`
# rejects (only `gavel test` accepts it), so run the binary directly.
- name: Install gavel
run: |
mkdir -p "$HOME/.local/bin"
curl -fsSL "https://github.com/flanksource/gavel/releases/download/${GAVEL_VERSION}/gavel_linux_amd64.tar.gz" -o /tmp/gavel.tar.gz
tar -xzf /tmp/gavel.tar.gz -C /tmp
install -m 0755 /tmp/gavel "$HOME/.local/bin/gavel"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
env:
GAVEL_VERSION: v0.0.39

- name: Gavel lint
run: gavel lint --no-progress --no-color

openapi:
name: OpenAPI Integration
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
cache: true

- name: Run OpenAPI integration tests
run: make test:openapi
env:
CGO_ENABLED: 1

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Comment on lines +83 to +98
Comment on lines +82 to +98

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add explicit permissions block to the openapi job.

The openapi job inherits default permissions, which may be overly broad. Explicitly grant only the minimum required permissions.

🔐 Proposed fix
   openapi:
     name: OpenAPI Integration
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
🧰 Tools
🪛 GitHub Check: CodeQL

[warning] 38-53: Workflow does not contain permissions
Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {{contents: read}}

🪛 zizmor (1.25.2)

[warning] 41-42: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 37-54: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block

(excessive-permissions)


[error] 42-42: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 45-45: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/gavel.yml around lines 37 - 53, The openapi job currently
inherits default workflow permissions; update the openapi job definition to
include an explicit permissions block that grants only the minimum required
permissions (for example permissions: contents: read and set any other
permissions to none or read as appropriate for the steps used). Locate the job
named "openapi" and add a permissions section under it (e.g., permissions: {
contents: read }) to restrict broad defaults while ensuring actions/checkout and
the test step have the required access.

93 changes: 0 additions & 93 deletions .github/workflows/lint.yml

This file was deleted.

119 changes: 0 additions & 119 deletions .github/workflows/test.yml

This file was deleted.

6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ test-*
.cache
*.db
clicky
!lint/testdata/src/github.com/flanksource/clicky/
!lint/testdata/src/github.com/flanksource/clicky/stub.go
.task
*.pdf
*.html
Expand Down Expand Up @@ -96,4 +98,8 @@ ginkgo.report
examples/uber_demo/uber_demo
.gavel/
examples/enitity/webapp/dist/
# Keep a committed placeholder so the //go:embed webapp/dist in main.go always
# resolves in CI; `pnpm build` overwrites dist/ with the real hashed bundles.
!examples/enitity/webapp/dist/
!examples/enitity/webapp/dist/index.html
examples/enitity/enitity
9 changes: 7 additions & 2 deletions ai/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import (

"github.com/flanksource/clicky/task"
"github.com/flanksource/commons/logger"
_ "github.com/mattn/go-sqlite3"
// Pure-Go SQLite driver (registers driver name "sqlite") so clicky builds
// without CGO. Use modernc.org/sqlite — the same driver gavel's cache
// registers — so a binary linking both registers the "sqlite" driver exactly
// once. (glebarez/go-sqlite registers the same name from a different package;
// mixing the two panics at init with "Register called twice".)
_ "modernc.org/sqlite"
)

var (
Expand Down Expand Up @@ -104,7 +109,7 @@ func New(config Config) (*Cache, error) {
}

// Open database
db, err := sql.Open("sqlite3", config.DBPath)
db, err := sql.Open("sqlite", config.DBPath)
if err != nil {
return nil, fmt.Errorf("failed to open database: %w", err)
}
Expand Down
Loading
Loading