Skip to content

Agent: fade long sidebar task titles #1118

Agent: fade long sidebar task titles

Agent: fade long sidebar task titles #1118

Workflow file for this run

name: Maple Agent CI
on:
push:
branches: [master]
pull_request:
# Run unprivileged validation for stacked PRs as well as master targets.
workflow_dispatch:
# PR code, including forks, executes only on fresh managed runners with a
# read-only token. No signing, release publication, environment, or deployment
# credentials belong in this workflow.
permissions:
contents: read
concurrency:
group: maple-agent-ci-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
CARGO_INCREMENTAL: 0
CARGO_PROFILE_DEV_DEBUG: 0
RUSTFLAGS: -D warnings
defaults:
run:
shell: bash
working-directory: apps/maple-agent
jobs:
changes:
name: Select Agent checks
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
agent: ${{ steps.classify.outputs.agent }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
persist-credentials: false
- name: Classify changed paths
id: classify
working-directory: .
env:
BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event.before }}
HEAD_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
run: |
set -euo pipefail
enable_agent() { echo 'agent=true' >> "$GITHUB_OUTPUT"; }
case "$GITHUB_EVENT_NAME" in
pull_request) separator='...' ;;
push)
separator='..'
if [[ "$BASE_SHA" =~ ^0+$ ]]; then
enable_agent
exit 0
fi
;;
*) enable_agent; exit 0 ;;
esac
if ! git cat-file -e "${BASE_SHA}^{commit}" || ! git cat-file -e "${HEAD_SHA}^{commit}"; then
enable_agent
exit 0
fi
changed_paths="$(mktemp)"
trap 'rm -f "$changed_paths"' EXIT
if ! git diff --no-renames --name-only -z "${BASE_SHA}${separator}${HEAD_SHA}" > "$changed_paths"; then
enable_agent
elif ! python3 scripts/ci/agent_change_detection.py < "$changed_paths" >> "$GITHUB_OUTPUT"; then
enable_agent
fi
desktop:
name: Agent (${{ matrix.os }})
needs: changes
# A failed selector must never silently omit validation.
if: ${{ always() && !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.agent != 'false') }}
runs-on: ${{ matrix.os }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
os: [blacksmith-8vcpu-ubuntu-2404, macos-26, windows-latest]
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install pinned Nix environment
if: runner.os != 'Windows'
uses: DeterminateSystems/determinate-nix-action@96c5ee93a9dddf2830d31e1da6ec719077336c28 # v3.23.3
with:
source-tag: v3.23.3
github-token: ""
- name: Verify pinned Nix runtime
if: runner.os != 'Windows'
working-directory: .
run: bash scripts/ci/verify-nix-runtime.sh
- name: Install pinned Windows Rust
if: runner.os == 'Windows'
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable action, exact toolchain below
with:
# Matches the component's frozen rust-overlay input.
toolchain: 1.98.0
- name: Select Windows MSVC and SDK
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@a102174a2b586eec2ea151a69e6fd14404a8ce7c # v1.13.0
with:
arch: x64
- name: Select native Windows Perl for the static crypto build
if: runner.os == 'Windows'
run: |
native_perl=/c/Strawberry/perl/bin/perl.exe
if [ ! -x "$native_perl" ]; then
echo 'Native Windows Perl is missing from the runner' >&2
exit 1
fi
"$native_perl" -MLocale::Maketext::Simple -MIPC::Cmd -e 'die "OpenSSL requires native Windows Perl\n" unless $^O eq "MSWin32"; print "$^V\n"'
# Pin the native executable across later Git Bash steps and Rust's
# process resolver instead of depending on their PATH ordering.
native_perl_windows="$(cygpath -m "$native_perl")"
printf 'OPENSSL_SRC_PERL=%s\n' "$native_perl_windows" >> "$GITHUB_ENV"
# openssl-src uses NASM if available and otherwise selects no-asm.
- name: Pin and smoke-test the selected Windows linker
if: runner.os == 'Windows'
run: python3 ../../scripts/ci/agent_windows.py
- name: Fingerprint the actual build environment
id: environment
run: |
if [ "$RUNNER_OS" = Windows ]; then
python3 ../../scripts/ci/agent_cache.py --profile ci --output "$RUNNER_TEMP/agent-environment.json"
else
nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_cache.py --profile ci --output "$RUNNER_TEMP/agent-environment.json"
fi
- name: Cache Agent Rust dependencies
id: rust-cache
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
workspaces: apps/maple-agent -> target
add-rust-environment-hash-key: "true"
# Dependency hashes belong in the action's exact suffix, not its restore prefix.
key: maple-agent-ci-v2-${{ steps.environment.outputs.compatibility }}
cmd-format: python3 "${{ github.workspace }}/scripts/ci/agent_cache_command.py" {0}
save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
- name: Check whether Cargo targets were restored
id: restored-target
run: |
if [ -f "$GITHUB_WORKSPACE/apps/maple-agent/target/CACHEDIR.TAG" ]; then
echo 'present=true' >> "$GITHUB_OUTPUT"
else
echo 'present=false' >> "$GITHUB_OUTPUT"
fi
- name: Restore compatible legacy Cargo targets on a cache miss
if: ${{ steps.rust-cache.outputs.cache-hit != 'true' && steps.restored-target.outputs.present != 'true' }}
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
workspaces: apps/maple-agent -> target
# Read only within the existing actual compiler/native ABI prefix.
# The primary cache retains its exact dependency suffix and owns saves.
add-rust-environment-hash-key: "false"
key: maple-agent-ci-v2-${{ steps.environment.outputs.compatibility }}
cmd-format: python3 "${{ github.workspace }}/scripts/ci/agent_cache_command.py" {0}
save-if: "false"
- name: Record the current build environment after restore
run: |
mkdir -p target/ci-metrics
cp "$RUNNER_TEMP/agent-environment.json" target/ci-metrics/environment.json
- name: Verify Git metadata freshness on native workspace builds
if: runner.os != 'Linux'
run: |
if [ "$RUNNER_OS" = Windows ]; then
python3 scripts/test_git_metadata.py
else
nix develop --no-update-lock-file . -c python3 scripts/test_git_metadata.py
fi
- name: Verify the canonical SDK and proxy dependency graph
run: |
metadata="$(mktemp)"
trap 'rm -f "$metadata"' EXIT
if [ "$RUNNER_OS" = Windows ]; then
cargo metadata --locked --format-version 1 > "$metadata"
else
# shellcheck disable=SC2016 # The child shell expands its own positional argument.
nix develop --no-update-lock-file . -c bash -c 'cargo metadata --locked --format-version 1 > "$1"' -- "$metadata"
fi
python3 ../../scripts/ci/verify-agent-rust-deps.py "$metadata"
if [ "$RUNNER_OS" = Windows ]; then
python3 scripts/verify-sqlcipher-build.py "$metadata"
else
nix develop --no-update-lock-file . -c python3 scripts/verify-sqlcipher-build.py "$metadata"
fi
- name: Format, lint, build, and test Linux feature matrix
if: runner.os == 'Linux'
run: nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_measure.py --phase linux-ci --target target -- just ci
- name: Build macOS workspace and test targets
if: runner.os == 'macOS'
run: nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_measure.py --phase macos-build --target target -- cargo build --workspace --all-targets --locked --timings
- name: Package and smoke macOS debug app
if: runner.os == 'macOS'
run: nix develop --no-update-lock-file . -c ./scripts/macos-debug-app.sh
- name: Test macOS workspace
if: runner.os == 'macOS'
run: nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_measure.py --phase macos-test --target target -- cargo test --workspace --locked --timings
- name: Build Windows workspace and test targets
if: runner.os == 'Windows'
run: python3 ../../scripts/ci/agent_measure.py --phase windows-build --target target -- cargo build --workspace --all-targets --locked --timings
- name: Test Windows workspace
if: runner.os == 'Windows'
run: python3 ../../scripts/ci/agent_measure.py --phase windows-test --target target -- cargo test --workspace --locked --timings
- name: Audit Agent dependencies
if: runner.os == 'Linux'
run: nix develop --no-update-lock-file . -c python3 scripts/audit-sqlcipher-dependencies.py
- name: Regenerate the signed SQLCipher source
if: runner.os == 'Linux'
run: |
metadata="$(mktemp)"
trap 'rm -f "$metadata"' EXIT
# shellcheck disable=SC2016 # The child shell expands its own positional argument.
nix develop --no-update-lock-file . -c bash -c 'cargo metadata --locked --format-version 1 > "$1"' -- "$metadata"
nix develop --no-update-lock-file . -c python3 dependencies/sqlcipher/verify_sqlcipher.py --metadata "$metadata"
- name: Summarize phase timings and target size
if: always()
run: python3 ../../scripts/ci/agent_measure.py --summarize target
- name: Upload bounded CI measurements
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: maple-agent-ci-metrics-${{ runner.os }}-${{ runner.arch }}-${{ github.run_id }}-${{ github.run_attempt }}
path: apps/maple-agent/target/ci-metrics/
if-no-files-found: warn
retention-days: 7
provider:
name: Agent provider (${{ matrix.os }})
needs: changes
if: ${{ always() && !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.agent != 'false') }}
runs-on: ${{ matrix.os }}
timeout-minutes: 90
strategy:
fail-fast: false
matrix:
os: [blacksmith-8vcpu-ubuntu-2404, macos-26, windows-latest]
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install pinned Nix environment
if: runner.os != 'Windows'
uses: DeterminateSystems/determinate-nix-action@96c5ee93a9dddf2830d31e1da6ec719077336c28 # v3.23.3
with:
source-tag: v3.23.3
github-token: ""
- name: Verify pinned Nix runtime
if: runner.os != 'Windows'
working-directory: .
run: bash scripts/ci/verify-nix-runtime.sh
- name: Install pinned Windows Rust
if: runner.os == 'Windows'
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable action, exact toolchain below
with:
# Matches the component's frozen rust-overlay input.
toolchain: 1.98.0
- name: Select Windows MSVC and SDK
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@a102174a2b586eec2ea151a69e6fd14404a8ce7c # v1.13.0
with:
arch: x64
- name: Select native Windows Perl for the static crypto build
if: runner.os == 'Windows'
run: |
native_perl=/c/Strawberry/perl/bin/perl.exe
if [ ! -x "$native_perl" ]; then
echo 'Native Windows Perl is missing from the runner' >&2
exit 1
fi
"$native_perl" -MLocale::Maketext::Simple -MIPC::Cmd -e 'die "OpenSSL requires native Windows Perl\n" unless $^O eq "MSWin32"; print "$^V\n"'
# Pin the native executable across later Git Bash steps and Rust's
# process resolver instead of depending on their PATH ordering.
native_perl_windows="$(cygpath -m "$native_perl")"
printf 'OPENSSL_SRC_PERL=%s\n' "$native_perl_windows" >> "$GITHUB_ENV"
# openssl-src uses NASM if available and otherwise selects no-asm.
- name: Pin and smoke-test the selected Windows linker
if: runner.os == 'Windows'
run: python3 ../../scripts/ci/agent_windows.py
- name: Select isolated provider paths
run: |
printf 'PROVIDER_WORK=%s/rusqlite-provider\nPROVIDER_TARGET=%s/rusqlite-provider-target\n' "$RUNNER_TEMP" "$RUNNER_TEMP" >> "$GITHUB_ENV"
- name: Prepare and verify the resolved upstream provider test graph
id: provider
run: |
metadata="$RUNNER_TEMP/provider-workspace-metadata.json"
if [ "$RUNNER_OS" = Windows ]; then
cargo metadata --locked --format-version 1 > "$metadata"
python3 scripts/test-rusqlite-provider.py "$metadata" --phase prepare --work-dir "$PROVIDER_WORK" --target-dir "$PROVIDER_TARGET" --github-output "$GITHUB_OUTPUT"
else
# shellcheck disable=SC2016
nix develop --no-update-lock-file . -c bash -c 'cargo metadata --locked --format-version 1 > "$1"' -- "$metadata"
nix develop --no-update-lock-file . -c python3 scripts/test-rusqlite-provider.py "$metadata" --phase prepare --work-dir "$PROVIDER_WORK" --target-dir "$PROVIDER_TARGET" --github-output "$GITHUB_OUTPUT"
fi
- name: Fingerprint the actual build environment
id: environment
run: |
if [ "$RUNNER_OS" = Windows ]; then
python3 ../../scripts/ci/agent_cache.py --profile provider --cargo-config-dir "$PROVIDER_WORK" --output target/ci-metrics/environment.json
else
nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_cache.py --profile provider --cargo-config-dir "$PROVIDER_WORK" --output target/ci-metrics/environment.json
fi
- name: Restore only matching verified provider artifacts
id: provider-cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ${{ env.PROVIDER_TARGET }}
key: maple-agent-provider-v2-${{ steps.environment.outputs.compatibility }}-${{ steps.provider.outputs.dependency-fingerprint }}
- name: Test released rusqlite against the static provider
run: |
metadata="$RUNNER_TEMP/provider-workspace-metadata.json"
if [ "$RUNNER_OS" = Windows ]; then
python3 ../../scripts/ci/agent_measure.py --phase provider-test --target "$PROVIDER_TARGET" -- python3 scripts/test-rusqlite-provider.py "$metadata" --phase run --work-dir "$PROVIDER_WORK" --target-dir "$PROVIDER_TARGET"
else
nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_measure.py --phase provider-test --target "$PROVIDER_TARGET" -- python3 scripts/test-rusqlite-provider.py "$metadata" --phase run --work-dir "$PROVIDER_WORK" --target-dir "$PROVIDER_TARGET"
fi
- name: Save trusted provider artifacts
if: ${{ success() && github.event_name == 'push' && github.ref == 'refs/heads/master' && steps.provider-cache.outputs.cache-hit != 'true' }}
uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ${{ env.PROVIDER_TARGET }}
key: ${{ steps.provider-cache.outputs.cache-primary-key }}
- name: Summarize phase timings and target size
if: always()
run: python3 ../../scripts/ci/agent_measure.py --summarize "$PROVIDER_TARGET"
- name: Upload bounded CI measurements
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: maple-agent-provider-metrics-${{ runner.os }}-${{ runner.arch }}-${{ github.run_id }}-${{ github.run_attempt }}
path: apps/maple-agent/target/ci-metrics/
if-no-files-found: warn
retention-days: 7
linux-release:
name: Agent Linux release binary
needs: changes
if: ${{ always() && !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.agent != 'false') }}
runs-on: blacksmith-8vcpu-ubuntu-2404
timeout-minutes: 90
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
persist-credentials: false
- name: Install pinned Nix environment
if: runner.os != 'Windows'
uses: DeterminateSystems/determinate-nix-action@96c5ee93a9dddf2830d31e1da6ec719077336c28 # v3.23.3
with:
source-tag: v3.23.3
github-token: ""
- name: Verify pinned Nix runtime
if: runner.os != 'Windows'
working-directory: .
run: bash scripts/ci/verify-nix-runtime.sh
- name: Fingerprint the actual build environment
id: environment
run: |
if [ "$RUNNER_OS" = Windows ]; then
python3 ../../scripts/ci/agent_cache.py --profile release --output "$RUNNER_TEMP/agent-environment.json"
else
nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_cache.py --profile release --output "$RUNNER_TEMP/agent-environment.json"
fi
- name: Cache Agent release dependencies
id: rust-cache
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
workspaces: apps/maple-agent -> target
add-rust-environment-hash-key: "true"
# Dependency hashes belong in the action's exact suffix, not its restore prefix.
key: maple-agent-release-v2-${{ steps.environment.outputs.compatibility }}
cmd-format: python3 "${{ github.workspace }}/scripts/ci/agent_cache_command.py" {0}
save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
- name: Check whether Cargo targets were restored
id: restored-target
run: |
if [ -f "$GITHUB_WORKSPACE/apps/maple-agent/target/CACHEDIR.TAG" ]; then
echo 'present=true' >> "$GITHUB_OUTPUT"
else
echo 'present=false' >> "$GITHUB_OUTPUT"
fi
- name: Restore compatible legacy Cargo targets on a cache miss
if: ${{ steps.rust-cache.outputs.cache-hit != 'true' && steps.restored-target.outputs.present != 'true' }}
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
workspaces: apps/maple-agent -> target
add-rust-environment-hash-key: "false"
key: maple-agent-release-v2-${{ steps.environment.outputs.compatibility }}
cmd-format: python3 "${{ github.workspace }}/scripts/ci/agent_cache_command.py" {0}
save-if: "false"
- name: Record the current build environment after restore
run: |
mkdir -p target/ci-metrics
cp "$RUNNER_TEMP/agent-environment.json" target/ci-metrics/environment.json
- name: Verify the canonical SDK and proxy dependency graph
run: |
metadata="$(mktemp)"
trap 'rm -f "$metadata"' EXIT
if [ "$RUNNER_OS" = Windows ]; then
cargo metadata --locked --format-version 1 > "$metadata"
else
# shellcheck disable=SC2016 # The child shell expands its own positional argument.
nix develop --no-update-lock-file . -c bash -c 'cargo metadata --locked --format-version 1 > "$1"' -- "$metadata"
fi
python3 ../../scripts/ci/verify-agent-rust-deps.py "$metadata"
if [ "$RUNNER_OS" = Windows ]; then
python3 scripts/verify-sqlcipher-build.py "$metadata"
else
nix develop --no-update-lock-file . -c python3 scripts/verify-sqlcipher-build.py "$metadata"
fi
- name: Generate and validate Linux third-party notices
if: runner.os == 'Linux'
run: |
nix develop --no-update-lock-file . -c python3 scripts/generate-third-party-notices.py
nix develop --no-update-lock-file . -c python3 scripts/generate-third-party-notices.py --check
- name: Build Linux release binary
if: runner.os == 'Linux'
run: nix develop --no-update-lock-file . -c python3 ../../scripts/ci/agent_measure.py --phase linux-release --target target -- cargo build --release -p maple-agent-app --locked --timings
# This is an unsigned CI build, never a GitHub Release or an updater feed.
- name: Upload Linux CI binary
if: runner.os == 'Linux'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: maple-agent-linux-x86_64-ci-${{ github.run_id }}-${{ github.run_attempt }}
path: |
apps/maple-agent/target/release/maple-agent
apps/maple-agent/target/third-party-notices
if-no-files-found: error
retention-days: 5
- name: Summarize phase timings and target size
if: always()
run: python3 ../../scripts/ci/agent_measure.py --summarize target
- name: Upload bounded CI measurements
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: maple-agent-release-metrics-${{ runner.os }}-${{ runner.arch }}-${{ github.run_id }}-${{ github.run_attempt }}
path: apps/maple-agent/target/ci-metrics/
if-no-files-found: warn
retention-days: 7
required:
name: Agent CI required jobs
needs: [changes, desktop, provider, linux-release]
if: ${{ always() && !cancelled() }}
runs-on: ubuntu-latest
timeout-minutes: 5
defaults:
run:
working-directory: .
steps:
- name: Require every selected platform and independent check
env:
SELECTOR_RESULT: ${{ needs.changes.result }}
AGENT_SELECTED: ${{ needs.changes.outputs.agent }}
DESKTOP_RESULT: ${{ needs.desktop.result }}
PROVIDER_RESULT: ${{ needs.provider.result }}
RELEASE_RESULT: ${{ needs.linux-release.result }}
run: |
set -euo pipefail
if [ "$SELECTOR_RESULT" = success ] && [ "$AGENT_SELECTED" = false ]; then
test "$DESKTOP_RESULT" = skipped
test "$PROVIDER_RESULT" = skipped
test "$RELEASE_RESULT" = skipped
else
test "$DESKTOP_RESULT" = success
test "$PROVIDER_RESULT" = success
test "$RELEASE_RESULT" = success
fi