Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
830abc9
ci: stop leaving the checkout token on disk
fstubner Oct 7, 2026
71d1293
ci: pin the publish dry run's toolchain action by commit
fstubner Oct 7, 2026
0eb3061
audit: drop cargo-audit ignores that no longer match anything
fstubner Oct 7, 2026
95ad4e4
dependabot: cover the MCP smoke test and the Linux check image
fstubner Oct 7, 2026
3b54cf5
publish: submit to winget with a pinned, digest-checked Komac
fstubner Oct 7, 2026
0f4a772
release: build into the draft, check every asset, then publish
fstubner Oct 7, 2026
fbf82a8
updater: bind every update signature to its version, and require it
fstubner Oct 7, 2026
e7f5001
release: keep the signing secrets out of the compile and npm install …
fstubner Oct 7, 2026
8690941
publish: crates.io token off argv, re-runnable crates job, signed MCP…
fstubner Oct 7, 2026
8faea26
site: present only published releases as released
fstubner Oct 7, 2026
bd877cc
pages: per-job permissions, MSI staging away from npm, published version
fstubner Oct 7, 2026
fab4966
preflight: check the signing credentials; lint the release PowerShell
fstubner Oct 7, 2026
c58ede8
install.sh: run everything from main(), called on the last line
fstubner Oct 7, 2026
346e0e7
install.sh: check the Sigstore signature when cosign is there; HTTPS …
fstubner Oct 7, 2026
72eaadc
install.ps1: run from a function and throw instead of exit
fstubner Oct 7, 2026
3c0e098
install.ps1: require netscli.exe's Authenticode signature
fstubner Oct 7, 2026
2e5ab9b
msstore-submit: keep the client secret and token off curl's command line
fstubner Oct 7, 2026
93697e0
ci: timeouts on the site and audit jobs, cargo-audit and wrangler pinned
fstubner Oct 7, 2026
fba39c1
ci: drop unmeasured durations from workflow comments
fstubner Oct 7, 2026
5083023
docs: describe the release pipeline as it now runs
fstubner Oct 7, 2026
a5b4c15
changelog: 0.3.5 entries for the release and installer changes
fstubner Oct 7, 2026
2ad0f33
Correct what the v0.3.4 outage broke
fstubner Oct 7, 2026
b2cbdbe
Signing environment: main only. Say what Komac's PR check really does.
fstubner Oct 7, 2026
e23803a
Merge remote-tracking branch 'origin/main' into fix/release-pipeline
fstubner Oct 7, 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
32 changes: 4 additions & 28 deletions .cargo/audit.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,6 @@ ignore = [

# -- Soundness warnings (transitive, not reachable via our usage) -----

# rand 0.7.3 unsoundness with a custom logger calling rand::rng().
# Transitive via Tauri's kuchikiki/selectors path; never invoked with
# a custom logger in our binaries.
"RUSTSEC-2026-0097",

# lru IterMut stacked-borrows violation. Transitive via ratatui; we
# don't touch IterMut on lru caches in application code.
"RUSTSEC-2026-0002",

# glib VariantStrIter Iterator/DoubleEndedIterator unsoundness.
# Transitive via Tauri 2; upstream Tauri is migrating to GTK4 which
# replaces this binding stack.
Expand All @@ -45,24 +36,9 @@ ignore = [

# -- Unmaintained: other transitive ------------------------------------

# proc-macro-error: transitive via dialoguer and other proc-macro
# consumers. A maintained fork (proc-macro-error2) exists but not every
# upstream has migrated. No exploitable surface.
# proc-macro-error: transitive via glib-macros and gtk3-macros, the same
# Tauri 2 GTK3 stack as above. A maintained fork (proc-macro-error2)
# exists but those crates have not migrated. Compile-time only, no
# runtime surface.
"RUSTSEC-2024-0370",

# paste: unmaintained but still widely used. Transitive via several
# crates; a fork exists. No runtime surface beyond compile-time macros.
"RUSTSEC-2024-0436",

# fxhash: transitive. rustc-hash is the maintained replacement but
# upstream deps still pin fxhash.
"RUSTSEC-2025-0057",

# unic-* crates: transitive via idna via url via ipnet and hickory.
# Unmaintained for years; idna is migrating off the unic- stack.
"RUSTSEC-2025-0075", # unic-char-range
"RUSTSEC-2025-0080", # unic-common
"RUSTSEC-2025-0081", # unic-char-property
"RUSTSEC-2025-0098", # unic-ucd-version
"RUSTSEC-2025-0100", # unic-ucd-ident
]
37 changes: 37 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,29 @@ updates:
- "@astrojs/*"
- "@astrojs/starlight"

# The MCP smoke test drives `netscli serve` with the official MCP SDK
# client, so it is a pinned npm project of its own. Its SDK version is the
# thing worth keeping current: the test exists because clients built on
# that SDK are the ones that dropped our replies.
- package-ecosystem: npm
directory: "/scripts/mcp-smoke"
schedule:
interval: monthly
open-pull-requests-limit: 3
labels:
- dependencies
- javascript
- scripts
groups:
mcp-smoke:
patterns:
- "*"

# packaging/npm/netscli/package.json is deliberately absent. It is a
# template: its version and its five optionalDependencies are @@VERSION@@
# placeholders that publish-npm.sh fills in, and the packages it names are
# this project's own, published by the same job.

# scripts/ has its own Cargo project.
- package-ecosystem: cargo
directory: "/scripts"
Expand All @@ -113,6 +136,20 @@ updates:
- patch
- minor

# scripts/linux-check.Dockerfile, the local Linux check image. Its only
# dependency is the rust base image, which is pinned to the toolchain in
# rust-toolchain.toml, so a PR here means a new Rust release is out. Bump
# rust-toolchain.toml, Cargo.toml's rust-version and the workflows'
# `toolchain:` inputs in the same change, or close it.
- package-ecosystem: docker
directory: "/scripts"
schedule:
interval: monthly
open-pull-requests-limit: 1
labels:
- dependencies
- scripts

# GitHub Actions workflow pins.
- package-ecosystem: github-actions
directory: "/"
Expand Down
20 changes: 18 additions & 2 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,21 @@ concurrency:
permissions:
contents: read

env:
# The latest release on crates.io when this was set (2026-10-07).
CARGO_AUDIT_VERSION: 0.22.2

jobs:
audit:
name: cargo audit
runs-on: ubuntu-latest
# GitHub's default would let a stalled run go on for six hours. 30
# leaves room for a cold cache, which compiles cargo-audit first.
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install Rust
# See ci.yml's lint job for why this pin keeps a `# stable` comment
Expand All @@ -61,16 +70,21 @@ jobs:
shared-key: audit

# Cache cargo-audit itself so we don't reinstall every run.
#
# Keyed on a version pinned here. The key used to be a constant,
# `cargo-audit-v1`, and the weekly run keeps a cache warm, so the
# binary installed once was never upgraded. Bump CARGO_AUDIT_VERSION
# to upgrade; the new key misses and reinstalls.
- name: Cache cargo-audit
id: cache-cargo-audit
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/.cargo/bin/cargo-audit
key: cargo-audit-v1
key: cargo-audit-${{ env.CARGO_AUDIT_VERSION }}

- name: Install cargo-audit
if: steps.cache-cargo-audit.outputs.cache-hit != 'true'
run: cargo install cargo-audit --locked
run: cargo install cargo-audit --version "$CARGO_AUDIT_VERSION" --locked

- name: Run cargo audit
run: cargo audit
Expand Down Expand Up @@ -106,6 +120,8 @@ jobs:
path: apps/netscli-gui
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
Expand Down
49 changes: 44 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
- id: filter
shell: bash
Expand Down Expand Up @@ -108,6 +109,8 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# 22, matching pages.yml / release.yml / site.yml / site-preview.yml.
Expand Down Expand Up @@ -139,11 +142,18 @@ jobs:
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# install.sh is user-facing; the release/ scripts hold GH_TOKEN and
# push to three package registries. Both are worth linting, and
# neither is exercised by any other job.
- name: shellcheck install.sh
run: shellcheck scripts/install.sh
run: shellcheck scripts/install.sh scripts/install_test.sh
# What install.sh checks before it installs, against a fake release:
# a wrong checksum or a signature that does not verify must stop it,
# and a download cut short must run nothing.
- name: test install.sh
run: bash scripts/install_test.sh
- name: shellcheck release scripts
run: shellcheck scripts/release/*.sh
# The publish path only executes during a release, so a regression in
Expand All @@ -157,18 +167,35 @@ jobs:
# reach, so its test answers in the API's place.
- name: test Store submission script
run: bash scripts/release/msstore-submit_test.sh
- name: PSScriptAnalyzer install.ps1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
# The last check before a release goes public, and the builder of the
# in-app updater's latest.json. Both run only during a release, and a
# mistake in the first one would let an incomplete release out.
- name: test release asset and updater manifest checks
run: node --test scripts/release/*.test.mjs
- name: PSScriptAnalyzer install.ps1 and the release scripts
shell: pwsh
# Write-Host is intentional here (colored installer UX output, which
# Write-Output can't do); the empty catch blocks are documented
# best-effort fallbacks (e.g. TLS 1.2 opt-in on older PowerShell);
# and BOM-less UTF-8 is the existing, working file encoding. None of
# these are correctness bugs, so they're excluded rather than
# rewriting a working installer for style alone.
#
# scripts/release/*.ps1 too. sign-windows-pe.ps1 and
# check-msi-signed.ps1 run only during a release, inside the Windows
# GUI build, and a failure in the first is what left v0.3.4 without
# Windows files for 1 h 38 min. Linting is the part of that path CI
# can reach without the signing credentials.
run: |
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser
$results = Invoke-ScriptAnalyzer -Path scripts/install.ps1 -Severity Warning,Error `
-ExcludeRule PSAvoidUsingWriteHost, PSAvoidUsingEmptyCatchBlock, PSUseBOMForUnicodeEncodedFile
$paths = @('scripts/install.ps1') + @(Get-ChildItem scripts/release/*.ps1 | ForEach-Object FullName)
$results = @($paths | ForEach-Object {
Invoke-ScriptAnalyzer -Path $_ -Severity Warning,Error `
-ExcludeRule PSAvoidUsingWriteHost, PSAvoidUsingEmptyCatchBlock, PSUseBOMForUnicodeEncodedFile
})
$results | Format-Table -AutoSize
if ($results.Count -gt 0) { exit 1 }

Expand All @@ -182,6 +209,8 @@ jobs:
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# libpcap-dev: netscli-core pcap feature. GTK/WebKit: netscli-gui
# (Tauri 2) — clippy --all-targets compiles the Tauri shell, which
# won't link without these even when we only intend to lint Rust.
Expand Down Expand Up @@ -247,6 +276,8 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

# Linux needs libpcap for netscli-core's pcap feature and GTK/WebKit
# for netscli-gui (Tauri 2). `cargo test --all` compiles the whole
Expand Down Expand Up @@ -350,6 +381,8 @@ jobs:
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# 22 — see the note on the maintainability job. This one is also
Expand Down Expand Up @@ -441,6 +474,8 @@ jobs:
os: ${{ github.event_name == 'pull_request' && fromJSON('["ubuntu-latest"]') || fromJSON('["ubuntu-latest", "windows-latest", "macos-latest"]') }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install system dependencies (Linux)
if: runner.os == 'Linux'
run: |
Expand Down Expand Up @@ -494,6 +529,8 @@ jobs:
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install system dependencies
run: |
# `|| true` so a broken third-party apt index cannot fail this job;
Expand All @@ -502,7 +539,9 @@ jobs:
sudo apt-get update || true
sudo apt-get install -y libpcap-dev pkg-config
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
# See the pin note on the lint job above. This was the one `uses:` in
# the repository still on a moving ref.
uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
with:
toolchain: "1.96.0"
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/gui-render.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ jobs:
timeout-minutes: 30
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install Rust
# See ci.yml's lint job for why this pin keeps a `# stable` comment
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/installer-upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
timeout-minutes: 45
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install Rust
uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/msstore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
timeout-minutes: 20
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Submit to the Store
env:
MSSTORE_TENANT_ID: ${{ secrets.MSSTORE_TENANT_ID }}
Expand Down
Loading
Loading