Commit Graph

170 Commits

Author SHA1 Message Date
Martin Vogel 4630af6437 Cancel superseded CI runs on new pushes
A new push to a PR (or ref) now cancels the in-progress validation for
the previous commit instead of letting obsolete pipelines run to
completion. Drafts deliberately keep the full gate set — multi-platform
feedback matters most during iteration.

Signed-off-by: Martin Vogel <martin.vogel@datadice.io>
2026-06-12 18:16:43 +02:00
Martin Vogel 3d9917f325 Add community files and strengthen the contribution terms
Adds the Contributor Covenant 2.1 code of conduct (canonical text,
byte-verified against upstream) and reproduction-first issue forms that
ask for shareable reproductions — dummy snippets or public OSS repos —
plus logs and exact commands, never proprietary code. CONTRIBUTING.md
now states explicitly that a Signed-off-by line certifies the DCO in
full for that contribution, with GitHub ToS inbound=outbound noted as
the independent backstop. The VirusTotal badge now points at the latest
release instead of a pinned historical scan.

Signed-off-by: Martin Vogel <martin.vogel@datadice.io>
2026-06-12 16:58:55 +02:00
Martin Vogel 578ac55664 Add lint and the test suite to PR validation
PRs now run security gates, lint, and the full test suite (perf
assertions excluded — they stay in dry runs and releases where a
timing-flaky red cannot block a merge). Builds, smoke and soak remain
maintainer-driven.

Signed-off-by: Martin Vogel <martin.vogel@datadice.io>
2026-06-12 15:57:08 +02:00
Martin Vogel eb2e8d5963 Limit PR validation to the security gates
Pull requests run the security island only — static audit, license
gates, and the CodeQL gate plus the ci-ok summary; the full dry-run
chain (lint/test/build/smoke) stays maintainer-driven via
workflow_dispatch. The CodeQL gate now resolves the PR head SHA instead
of the synthetic merge commit so it can find the analysis run.

Signed-off-by: Martin Vogel <martin.vogel@datadice.io>
2026-06-12 15:57:08 +02:00
Martin Vogel 54c0b87a1d Run the full validation pipeline on pull requests
Pull requests now execute the dry-run chain (security including the
license gates, lint, full test suite, all build legs, smoke) plus a
single ci-ok summary job that fails unless every stage succeeded.
Branch protection requires dco + ci-ok, so nothing unverified can merge
— including from admins. CodeQL also runs on pull requests so the
security island completes on PR commits.

Signed-off-by: Martin Vogel <martin.vogel@datadice.io>
2026-06-12 15:57:08 +02:00
Martin Vogel 2a0ec321c3 Adopt the Developer Certificate of Origin for all commits
Every commit must now carry a Signed-off-by trailer matching its
author, certifying the right to submit the change under the project's
MIT license (DCO 1.1, the Linux kernel mechanism). Enforcement is
strict at three layers: a commit-msg hook rejects unsigned commits
locally (scripts/install-git-hooks.sh), and the new DCO workflow
rejects every push and pull request containing one. Merge commits and
bot authors are exempt, matching standard DCO checks.

Signed-off-by: Martin Vogel <martin.vogel@datadice.io>
2026-06-12 14:31:55 +02:00
Martin Vogel 1b383e376a Run the gate self-test and provenance audit in the security workflow
The license gate now proves itself before running: a --selftest mode
plants an unlicensed vendored file and asserts the structural layer
detects it, so a silently broken gate can no longer pass. The
byte-identity provenance audit gains exit-code semantics (any verdict
outside the accepted set fails) and runs as a blocking step in the
security workflow for both dry runs and releases.
2026-06-12 13:24:07 +02:00
Martin Vogel 324b6fc547 Pin the registry sync to the dispatched release version
The server.json sync step read its version from pkg/npm/package.json,
which can lag behind the release being published in the dispatched
commit. Use the workflow's version input instead — it is authoritative
for the run.
2026-06-12 10:25:27 +02:00
Martin Vogel f0c9be19c5 Keep the publish chain alive when the soak stage is skipped
With soak_level=none the soak job is skipped; release-draft already
handles that with an explicit condition, but verify and the publish
jobs relied on the default success() check, which treats a skipped
ancestor as non-success and silently skips the whole publish chain.
Give each downstream job an explicit condition that only blocks on
real failures or cancellations.
2026-06-12 07:05:55 +02:00
Martin Vogel 487f3f945b Bundle third-party notices into release archives; extend release tooling
Release archives now carry THIRD_PARTY_NOTICES.md, generated by
scripts/gen-third-party-notices.sh from THIRD_PARTY.md, the grammar
manifest, and the per-component license texts; the Homebrew formula
and AUR PKGBUILD install it alongside the binary. The SBOM gains
per-component license metadata, corrected versions, and the previously
missing vendored libraries. The security workflow gains a
vendored-license scan with an explicit allow-list policy, and the
release workflow exposes a skip_perf input for releases that do not
touch pipeline logic.
2026-06-12 02:17:39 +02:00
Martin Vogel 16dc384128 Tag the dispatched sha in release-draft, not the checkout HEAD
The release tag must point at the commit the artifacts were built from (github.sha). The step tagged whatever the job checkout resolved to - the branch head at job START - so a commit pushed to main mid-run moved the tag target; when that head commit happened to touch .github/workflows/, the GitHub App token's tag push was rejected outright (refusing to create refs at workflow-modifying commits), failing the 0.8.0 draft.
2026-06-11 21:34:36 +02:00
Martin Vogel 3bbb6bb073 Inject the release version into npm/PyPI packaging at publish time
The 0.8.0 release failed at publish-registries because pkg/npm/package.json still carried the previous hand-pinned version and npm refuses to publish over an existing release. The job now rewrites pkg/npm/package.json and pkg/pypi/pyproject.toml from the workflow's version input (with grep verification that the injection took) before publishing, so a forgotten manual bump can never fail the pipeline again. server.json needs no injection - publish-mcp-registry already syncs it from the published npm package.
2026-06-11 21:01:11 +02:00
Martin Vogel 9dbed50068 Move Glama packaging into pkg/glama; drop redundant packaging/ dir
packaging/glama -> pkg/glama so all packaging lives under pkg/. Update the
_smoke.yml job command and the Dockerfile/comment references to the new path.
verify.sh is path-relative (dirname $0), so its logic is unchanged.
2026-06-09 13:57:12 +02:00
Martin Vogel 69c16cada4 fix: deliver the static -portable linux binary on all install/update paths
The standard linux release binary dynamically links glibc 2.38+ and
GLIBCXX_3.4.32, so it fails to start on Debian 11, Ubuntu 20.04/22.04,
RHEL/Rocky 8/9, Amazon Linux 2, etc. — yet install.sh, the npm and PyPI
wrappers, and the binary's own self-update all fetched it by default,
contradicting the "single static binary" promise.

Point every linux install + self-update path at the fully-static
"-portable" asset (gcc -static), which has no glibc floor. macOS/Windows
are unaffected and unchanged.

- install.sh, pkg/npm/install.js, pkg/pypi _cli.py: select -portable on linux
- src/cli/cli.c: self-update download URL AND checksum archive name both use
  -portable on linux (they must match or the update fails checksum verify)
- scripts/smoke-test.sh: assert linux self-update targets the -portable asset
- scripts/ci/check-glibc-compat.sh: new guard — runs the binary inside
  debian:bullseye (glibc 2.31) and asserts it starts
- _smoke.yml: run the guard on the portable binary in smoke-linux-portable

Reproduced: standard binary -> "GLIBC_2.38 not found" on glibc 2.31;
portable binary runs cleanly.
2026-06-09 11:36:00 +02:00
Martin Vogel fa1021630a Add Glama directory integration (glama.json + check image)
- glama.json claims maintainership on glama.ai.
- packaging/glama/Dockerfile wraps the static Linux binary in a minimal
  image so Glama can launch the stdio server and run its MCP introspection
  checks (which power the directory score badge). The tool needs no Docker
  to run; this image is only for the directory integration. Fetches the
  latest release binary, arch-aware via TARGETARCH.
- packaging/glama/verify.sh builds the image and asserts the server answers
  initialize + tools/list with no project indexed.
- _smoke.yml runs verify.sh as a non-gating job (continue-on-error) so the
  integration is guarded against drift without ever blocking a release.
2026-06-09 11:36:00 +02:00
Martin Vogel 9507c4b0a1 Add official MCP Registry publishing to the release pipeline
- Add `mcpName` to the npm package and an `mcp-name:` marker to the PyPI
  README so the registry can verify package ownership for both.
- Rewrite server.json to reference the npm + PyPI packages instead of
  five per-platform mcpb tarballs. The old form was pinned to a stale
  0.6.1 with hardcoded SHA-256s that needed manual updates every release;
  the package form only needs a version sync. Also trims the description
  to the registry's 100-character limit.
- Add a publish-mcp-registry job: downloads mcp-publisher, authenticates
  via GitHub Actions OIDC (no token, no device flow), syncs server.json's
  version to the just-published npm package, and publishes. It runs after
  npm/PyPI but does not gate the release un-draft, so a registry outage
  never blocks shipping and the job can be retried on its own.
2026-06-09 11:36:00 +02:00
DeusData bd6d617bcf ci: deploy Pages via Actions, scoped to docs changes (#425)
The legacy "Deploy from a branch" Pages build ran Jekyll on every push to
main and failed on the planning docs under /docs — Jekyll's Liquid parser
hit `Unknown tag 'data'` in EVALUATION_PLAN.md, so the website build went
red after nearly every commit.

/docs is a hand-written static site (index.html + robots/sitemap/llms.txt),
so it never needed Jekyll. Deploy it with a GitHub Actions workflow that
uploads /docs as-is and only triggers on docs/** changes, and add a
.nojekyll guard. Switch the Pages source to "GitHub Actions" for this to
take over from the legacy build.

Co-authored-by: DeusData <joerge@datadice.io>
2026-06-08 18:26:11 +02:00
dependabot[bot] 200382167f build(deps): bump github/codeql-action from 4.36.0 to 4.36.2 (#419)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.36.0 to 4.36.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/7211b7c8077ea37d8641b6271f6a365a22a5fbfa...8aad20d150bbac5944a9f9d289da16a4b0d87c1e)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-07 02:31:27 +02:00
dependabot[bot] e5ea9eab32 build(deps): bump actions/checkout from 6.0.2 to 6.0.3 (#418)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...df4cb1c069e1874edd31b4311f1884172cec0e10)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-07 02:31:25 +02:00
Martin Vogel 0240d89168 Raise the build job timeout to 25 minutes
The slow macos-15-intel Intel runner occasionally exceeds the 15-minute build limit (timeout -> cancelled -> missing darwin-amd64 artifact -> cascaded smoke download failures). Give the build legs headroom, matching the test-job bump.
2026-06-06 17:03:19 +02:00
Martin Vogel 93e4f03d98 Raise the test job timeout to 60 minutes
The full suite runs the perf/bench/stress/scale suites, which push the slower ubuntu-24.04-arm runner right up against the 30-minute limit (flaky timeout cancellations marked as 'cancelled'). Give the slow legs headroom so the suite completes deterministically.
2026-06-06 15:45:25 +02:00
Martin Vogel 49bb9f616c Install git in the Windows msys2 test environment
Test legs (watcher, FILE_CHANGES_WITH, integration) need git; the CLANG64 env didn't include it.
2026-06-06 14:57:30 +02:00
Martin Vogel eed87fd372 Forbid test skips and convert existing skips to hard failures
Add scripts/check-no-test-skips.sh (run from lint) which fails the lint phase on any plain SKIP() or direct tf_skip_count manipulation; only SKIP_PLATFORM() (for genuinely platform-specific tests) is tolerated. Add FAIL() and SKIP_PLATFORM() helpers to the test framework and convert the remaining SKIP()/perf-gated skips across the suite into pass-or-fail assertions, so a suite that cannot meet its preconditions reports a red failure instead of a silent skip.
2026-06-05 21:53:25 +02:00
Martin Vogel 9538445278 Make the macOS Intel build leg blocking so darwin-amd64 always ships
The macos-15-intel leg had continue-on-error, so when that runner was unavailable the darwin-amd64 artifact silently never built and releases shipped with no Intel macOS binary. Remove continue-on-error so the leg is blocking - the binary ships or the build fails loudly. macos-15-intel is GitHub's supported Intel image through Aug 2027.
2026-06-05 21:53:25 +02:00
Martin Vogel 7fad5bc87b ci(dry-run): stop scarce Intel-macOS runner from gating smoke/soak
GitHub is sunsetting Intel-macOS runners, so the macos-15-intel build leg is
repeatedly cancelled before it can be allocated, turning the aggregate build
result non-success and skipping the smoke + soak jobs even though every other
build/test passed.

Mark only the macos-15-intel matrix leg continue-on-error, and relax the
smoke/soak gate to run unless builds were skipped or a leg genuinely failed
(tolerating a cancelled aggregate caused solely by the non-blocking Intel leg).
All other platforms remain required.
2026-05-31 16:06:06 +02:00
Martin Vogel 9dcc0e3c59 ci: remove temporary Windows repro harness
#394 group triaged: #266/#274/#331/#347/#348 verified fixed on v0.7.0 in
Windows CI; #227/#367 (SMB) pending reporter retest. Removing the throwaway
workflow.
2026-05-31 12:59:09 +02:00
Martin Vogel d198403e21 ci(temp): Windows repro harness for #394 group
Indexes a repo at a C:\ drive-letter path (subdirs + .cbmignore +
.mjs/.js) on windows-latest and dumps diagnostics for #347/#227/#367/
#331/#266/#274/#348. Temporary — delete after the run.
2026-05-31 12:51:20 +02:00
Martin Vogel d0e1e77825 ci: remove temporary bucket-B repro harness
The #336 (Icinga2/Linux) and #385 (KiCad/Windows) reproductions are done —
both index cleanly on v0.7.0 on their reported platforms. Removing the
throwaway workflow.
2026-05-31 00:51:14 +02:00
Martin Vogel 6c6b8c82b8 ci(temp): build bucket-B repro inline per-platform (avoid macos infra cancel)
The reused _build.yml builds all platforms; a cancelled macos-15-intel
runner skipped the icinga2/kicad index jobs. Build inline in each job so
the Linux (#336) and Windows (#385) repros don't depend on unrelated
platforms. Still temporary — delete after the run.
2026-05-31 00:42:46 +02:00
Martin Vogel c6c1d77c43 ci(temp): bucket-B crash repro harness (#336 icinga2 / #385 kicad)
Temporary workflow_dispatch harness: builds current-main binaries and
indexes Icinga2 on Linux (fast) and KiCad on Windows (moderate) to check
whether the reported crashes still reproduce on v0.7.0. To be removed
after the run.
2026-05-31 00:24:57 +02:00
dependabot[bot] 4fd6e1bd27 ci(deps): bump actions/setup-python from 5.6.0 to 6.2.0 (#329)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5.6.0 to 6.2.0.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/a26af69be951a213d495a4c3e4e4022e16d87065...a309ff8b426b58ec0e2a45f0f869d46889d02405)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 15:52:46 +02:00
dependabot[bot] 694652fc72 ci(deps): bump sigstore/cosign-installer from 4.1.1 to 4.1.2 (#328)
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 4.1.1 to 4.1.2.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003...6f9f17788090df1f26f669e9d70d6ae9567deba6)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 15:52:17 +02:00
dependabot[bot] 5c743e8e62 ci(deps): bump github/codeql-action from 4.35.2 to 4.36.0 (#368)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.35.2 to 4.36.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/95e58e9a2cdfd71adc6e0353d5c52f41a045d225...7211b7c8077ea37d8641b6271f6a365a22a5fbfa)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.36.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-30 15:52:06 +02:00
Martin Vogel d5742aab90 ci(codeql): revert CodeQL gate hardening from 27e640b
Reverts the CodeQL portion of 27e640b ('fix(mcp,ci): harden
get_architecture serialization + CodeQL gate'). Leaves the mcp.c +
test_mcp.c changes (NULL-coercion, clusters/services serialization,
extract_text_content fix, regression test) intact.

Restored to the pre-27e640b state:
  - drop 'jq' from build-deps install line
  - drop 'queries: +./codeql' from codeql-action/init (no ./codeql
    custom-query directory exists in this repo)
  - drop 'id: analyze' and 'output: codeql-results' on analyze step
  - drop the SARIF-parsing 'Fail on CodeQL error-level findings' step

CI workflow changes need their own design discussion per CONTRIBUTING.md
('Project configuration / CI workflows' is in the explicit-approval list);
the gate hardening landed bundled with an unrelated bug fix. Splitting it
out so the upstream MCP fix stays clean and any future CodeQL gate work
can be its own focused PR.
2026-05-09 16:52:11 +02:00
Martin Vogel 27e640b3b0 fix(mcp,ci): harden get_architecture serialization + CodeQL gate
Follow-up to #281 (handle_get_architecture) plus a CodeQL workflow
upgrade developed in parallel; bundling into one commit because the
test suite had to land alongside both.

mcp.c — handle_get_architecture
- NULL-coerce every const-char* field in the architecture sections
  via `x ? x : ""`, matching the rest of mcp.c (search_graph, etc.).
  Without this, a NULL field becomes a missing JSON key instead of
  an empty string; yyjson_mut_obj_add_str returns false on NULL and
  silently no-ops, so an inconsistent omission could surprise callers.
- Serialize two more architecture aspects that #281 left on the
  floor: services (cbm_service_link_t: from/to/type/count) and
  clusters (cbm_cluster_info_t: id/label/members/cohesion plus the
  top_nodes / packages / edge_types string arrays). The store-side
  computation populates these for aspects=["all"] / explicit names,
  so dropping them in the serializer was data loss.

tests/test_mcp.c
- New tool_get_architecture_emits_populated_sections regression test.
  Uses a minimal inline fixture (single Function node tagged with
  "is_entry_point": true) since arch_entry_points reads that flag
  out of properties_json. Asserts the response contains both an
  "entry_points" array and the function name — neither would appear
  before #281 because handle_get_architecture never called
  cbm_store_get_architecture.
- extract_text_content drilled too shallow: it pulled "content" only
  from the JSON root, so it worked for cbm_mcp_handle_tool but
  silently fell through to the raw response for cbm_mcp_server_handle
  (where content lives under .result.content). Added a fallback that
  checks .result.content; both unwrappers tested by existing fixtures.

ci(codeql)
- Run on pull_request to main, not just push; surfaces findings on
  the PR instead of after merge.
- Pull custom queries from ./codeql via `queries: +./codeql`.
- Capture SARIF output and fail the job on any error-level finding,
  using jq to enumerate rule id, file:line, and message text in the
  GitHub Actions error annotation. Warnings are still reported as
  before; only errors block.

Full suite: 2842 passed, 0 failed.
2026-05-09 16:37:53 +02:00
dependabot[bot] d27f4aa8c6 ci(deps): bump actions/setup-node from 6.3.0 to 6.4.0 (#289)
Patch bump (PR title was rebased to 4.2.0->6.4.0 originally; current diff is 6.3.0 -> 6.4.0).
2026-05-09 01:27:26 +02:00
dependabot[bot] d70c71776c ci(deps): bump msys2/setup-msys2 from 2.31.0 to 2.31.1 (#268)
Patch bump applied across _build.yml, _smoke.yml, _soak.yml, _test.yml.
2026-05-09 01:27:14 +02:00
dependabot[bot] 3bf38c962d ci(deps): bump github/codeql-action from 4.35.1 to 4.35.2 (#270)
Patch bump for codeql-action across codeql.yml and scorecard.yml.
2026-05-09 01:26:58 +02:00
dependabot[bot] 5da650ff74 ci(deps): bump actions/cache from 5.0.4 to 5.0.5 (#269)
Patch bump.
2026-05-09 01:26:47 +02:00
dependabot[bot] f81065d3fb ci(deps): bump softprops/action-gh-release from 2.6.1 to 3.0.0 (#267)
v3.0.0 moves the action runtime from Node 20 to Node 24. GitHub-hosted runners (which this repo uses) already support the Node 24 Actions runtime, so the upgrade is transparent.
2026-05-09 01:26:27 +02:00
Dustin Obrecht 2d00c4a337 fix: GitHub Actions shell injection in _build.yml (#249)
Replace direct `${{ ... }}` interpolation in `run:` steps of `.github/workflows/_build.yml` with `env:` blocks per GitHub's hardening guide. Every workflow input (`inputs.version`) and matrix value (`matrix.cc`, `matrix.cxx`, `matrix.goos`, `matrix.goarch`, `matrix.arch`) now flows into the shell through a named environment variable rather than being textually spliced into the script.

Pattern applied uniformly across the 6 flagged steps plus the archive steps that used `${{ matrix.* }}` in tar filenames. The values become opaque shell variables on expansion, so attacker input becomes a literal argv entry rather than interpreted shell code. The if/else form on `$VERSION` avoids word-splitting pitfalls of conditional arg construction.

semgrep `run-shell-injection` findings: 6 → 0. Behaviour preserved — same build.sh invocations, same artefact names, same conditional version handling.

Reference: https://securitylab.github.com/research/github-actions-untrusted-input/

Closes #247.
2026-05-09 00:40:26 +02:00
Martin Vogel 3305c1f9d3 fix(security): widen release audit to all files in binaries/
Previously the verify job only ran scripts/security-strings.sh on
files matching binaries/codebase-memory-mcp* — install.sh, install.ps1,
LICENSE, and any future companion files in the release archives were
NOT covered by the binary-string audit (only by VirusTotal).

Changes:
- release.yml: loop over binaries/* (every file in the audit set).
- security-strings.sh: detect file type via 'file -b'. For shell
  scripts and other text files, skip the URL audit and dangerous-cmd
  audit (those rules are tuned for compiled binaries — install.sh
  legitimately uses wget as a curl fallback, and 'case https://*)'
  globs look like unauthorized URLs to a strings dump). Always run
  credential and base64 pattern audits — those are universally
  meaningful regardless of file type.
- Verified locally: install.sh and install.ps1 now both pass.

Net effect: every release artifact is now audited, with rule sets
appropriate to its file type.
2026-05-05 00:59:58 +02:00
Martin Vogel 4fdcdd4239 fix(security): close open scanner alerts
Dependabot/CodeQL #33 — postcss XSS GHSA-qx2v-qp2m-jg93:
  npm audit fix in graph-ui (8.5.8 -> 8.5.14, above the <8.5.10 vuln range)

CodeQL #39 — TOCTOU race in artifact.c ensure_gitattributes():
  Replace stat() + fopen() with open(O_WRONLY|O_CREAT|O_EXCL).
  Atomic create-only-if-absent closes the check-vs-write window.
  Falls through to merge driver setup if file already exists.

CodeQL #55 — pip install not pinned in release.yml:
  Pin build==1.3.0 and twine==6.2.0. Comment explains why
  --require-hashes is not used (transitive-deps overhead).

Dismissed (won't-fix):
  - #56 contents: write — required for 'gh release edit --draft=false';
    no narrower permission exists.
  - #54-51 Crystal grammar warnings — vendored upstream code.
  - #50-40 Agda grammar warnings — vendored upstream code.
2026-05-05 00:51:52 +02:00
Martin Vogel 6aab9d5693 fix(release): atomic publish — un-draft GH release only after registries succeed
Previously the un-draft step ran inside the verify job, before
publish-registries. If npm or PyPI publish failed, the GitHub release
was already live but the wrappers were not — half-shipped state.

Move the un-draft into a new publish-final job that needs both
[verify, publish-registries]. If any registry fails, the GH release
stays in draft and the run can be re-tried with replace=true.
2026-05-04 23:21:26 +02:00
Martin Vogel 4cdc2dc9f3 feat(release): auto-publish npm and PyPI wrappers
Add publish-registries job to release.yml that runs after verify
(release published, VirusTotal table appended). Publishes:

- pkg/npm via 'npm publish --access public --provenance'
- pkg/pypi via 'twine upload' (sdist + wheel from hatchling)

Both wrappers fetch the binary at install time, so a version bump is
the only per-release change needed. Bumped to 0.6.1.

Requires NPM_TOKEN and PYPI_TOKEN repo secrets.
2026-05-04 23:17:51 +02:00
DeusData 68dd64ce23 Bump actions/upload-artifact from 7.0.0 to 7.0.1
Bump actions/upload-artifact from 7.0.0 to 7.0.1
2026-04-15 22:40:10 +01:00
DeusData ae3e1645e9 Bump actions/attest-sbom from 2.4.0 to 4.1.0
Bump actions/attest-sbom from 2.4.0 to 4.1.0
2026-04-15 22:40:07 +01:00
DeusData 0a07187bbd Fix VirusTotal links to use binary hashes instead of archive hashes
checksums.txt contains hashes of .tar.gz/.zip archives; VirusTotal
indexes the extracted binaries. Updated README table and badge to use
correct binary SHA-256 hashes for v0.6.0. Updated release.yml to hash
extracted binaries from the binaries/ directory for future releases.
2026-04-12 20:27:54 +01:00
DeusData fb738e4cb3 Add VirusTotal scan links, SLSA badge, and Security section to README
- Adds VirusTotal (0/72) and SLSA Level 3 badges to the header
- Adds Security section with per-binary VirusTotal scan links for v0.6.0
- Adds step in release.yml to auto-append a Security Verification table
  with per-binary VirusTotal links to every release's notes going forward
2026-04-12 19:18:29 +01:00
dependabot[bot] fb4c0d0783 Bump actions/upload-artifact from 7.0.0 to 7.0.1
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/bbbca2ddaa5d8feaa63e36b76fdaad77386f024f...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-11 05:42:48 +00:00