Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
143 changes: 143 additions & 0 deletions .github/workflows/test-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Test Action

# Exercises action.yml itself (the root-level composite "Setup Fledge" action),
# not the fledge binary's own test suite (that's ci.yml). This action exists
# because a silent break in the curl-based install workaround cost
# CorvidLabs/rune several CI runs, so it is covered on every PR and on main.
# See AGENTS.md and action.yml.

permissions:
contents: read

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

concurrency:
group: test-action-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
install:
name: install (${{ matrix.os }}, ${{ matrix.version }})
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
version: [v1.7.2, latest]
steps:
- uses: actions/checkout@v5

- id: setup
uses: ./
with:
version: ${{ matrix.version }}

- name: Verify outputs
shell: bash
env:
REQUESTED: ${{ matrix.version }}
GOT_VERSION: ${{ steps.setup.outputs.version }}
GOT_PATH: ${{ steps.setup.outputs.path }}
run: |
set -euo pipefail

if [ -z "$GOT_VERSION" ]; then
echo "::error::outputs.version is empty" >&2
exit 1
fi
if [ -z "$GOT_PATH" ]; then
echo "::error::outputs.path is empty" >&2
exit 1
fi

# A pinned version must round-trip unchanged; "latest" must resolve
# to a real vX.Y.Z tag rather than passing the literal through.
if [ "$REQUESTED" != "latest" ] && [ "$GOT_VERSION" != "$REQUESTED" ]; then
echo "::error::pinned version ${REQUESTED} but outputs.version was ${GOT_VERSION}" >&2
exit 1
fi

"$GOT_PATH" --version
command -v fledge

refuses-unsafe-install:
name: refuses unsafe and unverifiable installs
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v5

# curl normalizes dot segments before sending, so an unvalidated `..`
# here would pull the binary from a different repo entirely — and the
# action installs it 0755 and runs it.
- id: traversal
uses: ./
continue-on-error: true
with:
version: ../../../octocat/Hello-World/releases/download/v1

# v0.5.0 really does publish fledge-linux-x86_64 with no .sha256 beside
# it, which makes it a live fixture for the missing-sidecar path: the
# install has to fail rather than quietly degrade to unverified.
- id: unverifiable
uses: ./
continue-on-error: true
with:
version: v0.5.0

- name: Confirm both were refused
shell: bash
env:
TRAVERSAL: ${{ steps.traversal.outcome }}
UNVERIFIABLE: ${{ steps.unverifiable.outcome }}
run: |
set -euo pipefail
failed=0

if [ "$TRAVERSAL" != "failure" ]; then
echo "::error::a version containing '..' was accepted; the version validation in action.yml has regressed" >&2
failed=1
fi
if [ "$UNVERIFIABLE" != "failure" ]; then
echo "::error::v0.5.0 publishes no .sha256 sidecar but installed anyway; checksum verification is no longer mandatory" >&2
failed=1
fi

if [ "$failed" -ne 0 ]; then
exit 1
fi
echo "Confirmed: traversal version rejected, unverifiable release refused."

windows-unsupported:
name: windows is refused with a readable message
runs-on: windows-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v5

# fledge does publish fledge-windows-x86_64.exe; this action just doesn't
# install it yet. The message the action prints has to say that, not
# imply the binary is missing.
- id: setup
uses: ./
continue-on-error: true
with:
version: v1.7.2

- name: Confirm it failed for the right reason
shell: bash
env:
OUTCOME: ${{ steps.setup.outcome }}
run: |
set -euo pipefail
if [ "$OUTCOME" != "failure" ]; then
echo "::error::expected the action to fail on windows-latest, but it succeeded. If Windows support was added, update this job and README.md." >&2
exit 1
fi
echo "Confirmed: the action refuses Windows cleanly, as expected."
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"schema_version": 1,
"id": "CHG-0007-name-the-two-remaining-json-schema-version-literals-as-per-command-constants",
"slug": "name-the-two-remaining-json-schema-version-literals-as-per-command-constants",
"title": "Name the two remaining --json schema_version literals as per-command constants",
"description": "Name the two remaining --json schema_version literals as per-command constants",
"kind": "refactor",
"state": "archived",
"canonical_applied": true,
"base_commit": "df9ea9c5fd2b6d553a4334afecfbd04cbe23281b",
"created_at": 1785888531,
"updated_at": 1786816918,
"affected_specs": [],
"affected_paths": [
"src/envelope.rs",
"src/lanes/mod.rs",
"src/lanes/validate.rs",
"src/plugin/mod.rs",
"src/plugin/validate.rs",
".specsync/change-sequence.json"
],
"no_spec_change": true,
"no_spec_change_rationale": "Introduces named per-command schema constants and envelope tests only; emitted JSON bytes are unchanged, so no canonical spec contract moves.",
"acceptance_criteria": [
"cargo test, cargo clippy --all-targets -- -D warnings and cargo fmt --check are green; fledge plugins validate --json and fledge lanes validate --json emit byte-identical output to before the change; PLUGINS_VALIDATE_SCHEMA and LANES_VALIDATE_SCHEMA are defined beside the existing per-command constants and used at their call sites; envelope tests cover resource byte-identity and versioned struct flattening."
],
"selected_artifacts": [
"context",
"plan",
"testing",
"design",
"tasks"
],
"dependencies": [],
"answers": {
"architecture_risk": "no",
"public_contract": "no"
}
}
6 changes: 3 additions & 3 deletions .specsync/change-sequence.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schema_version": 1,
"sequence": 7,
"id": "CHG-0007-name-the-two-remaining-json-schema-version-literals-as-per-command-constants",
"sequence": 9,
"id": "CHG-0009-harden-the-setup-fledge-composite-action-after-pr-511-review-validate-the-vers",
"acknowledged_collisions": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{
"approvals": [
{
"gate": "definition",
"actor": "0xLeif",
"timestamp": 1786816279,
"digest": "f0652c769312ce8a726bb093368dfb12813885d2e6ec4e0a5b72767a83fc164a",
"note": null
},
{
"gate": "definition",
"actor": "0xLeif",
"timestamp": 1786817209,
"digest": "81d6b1c401a7ef49d768e85aae57caf9905f1e5f8784d7b879866b99bc1c8444",
"note": "Re-approval: only tasks.md checkboxes changed to reflect completed implementation work; scope, requirements, and risk answers unchanged from the originally-approved definition."
},
{
"gate": "acceptance",
"actor": "0xLeif",
"timestamp": 1786817880,
"digest": "ec2f5be6cd7c274875cd4d19ff9ef9723da327aeb5ad50b5f254732e921311c0",
"note": "Closing approval granted by repository owner via agent-mediated review; verify-native lane green, real end-to-end verification against v1.7.2 and latest performed."
},
{
"gate": "acceptance",
"actor": "0xLeif",
"timestamp": 1786922144,
"digest": "65d6d9bccba114e9e15d5da5ad19fa5959dd5e8fa63f51bad86c0b3fb43b1794",
"note": "Evidence refreshed after the PR #511 review response. CHG-0008's definition is byte-identical to what was originally accepted; the amended requirements live in CHG-0009, since specsync freezes the definition of an applied change. verify-native lane green against the current tree."
}
],
"reopenings": [
{
"schema_version": 1,
"change_id": "CHG-0008-add-root-level-action-yml-github-action-for-installing-fledge-in-ci",
"actor": "0xLeif",
"reason": "PR #511 review response (CHG-0009) amended action.yml, .github/workflows/test-action.yml and README.md after CHG-0008 was accepted, and creating CHG-0009 bumped .specsync/change-sequence.json, which CHG-0008 also lists as a delivery input. CHG-0008's definition is unchanged and stays frozen; this reopen only refreshes its verification evidence against the current tree.",
"timestamp": 1786921833,
"from_state": "accepted",
"to_state": "verifying",
"superseded_approval": {
"gate": "acceptance",
"actor": "0xLeif",
"timestamp": 1786817880,
"digest": "ec2f5be6cd7c274875cd4d19ff9ef9723da327aeb5ad50b5f254732e921311c0",
"note": "Closing approval granted by repository owner via agent-mediated review; verify-native lane green, real end-to-end verification against v1.7.2 and latest performed."
},
"prior_verification": {
"timestamp": 1786817238,
"commit": "6eb7a3ea595c949f4bc0078c0738508d800356b3",
"contract_digest": "81d6b1c401a7ef49d768e85aae57caf9905f1e5f8784d7b879866b99bc1c8444",
"workspace_digest": "dc0b6c7f33d78a8c862c97a87e9fa74dcd7697323c0d007fef4c66bb3a532102",
"acceptance_input_digest": "32c7dddda1effbe78b0258768b9dea3ebce4fba92dcbe256af1cdd45f6719fe7",
"acceptance_manifest": {
"schema_version": 1,
"entries": [
{
"path": ".github/workflows/test-action.yml",
"kind": "file",
"mode": 33188,
"payload_digest": "252a0a9d38bb6ccd9aea072ddea6694f377e022285683930638a45d7eb71f11d",
"entry_digest": "e09a496b47d5c9bb5de81d5e57b7e528d722121910ba1edb9999e2d77d88d7bd",
"owners": [
"@exact:delivery"
]
},
{
"path": ".specsync/change-sequence.json",
"kind": "file",
"mode": 33188,
"payload_digest": "7011d0028ec3b0acea0cb9b2f7b91b7abe4382986b4b2bf22f4307b4accbdce6",
"entry_digest": "78e4bd79b42a8aa8798ce1047416397125190f82146ed75ce1d20a316b8512de",
"owners": [
"@exact:delivery"
]
},
{
"path": "CONTRIBUTING.md",
"kind": "file",
"mode": 33188,
"payload_digest": "1c456009ea1d97960722bd763e9a2f7d43360ea561f0498d3cdcc627752a4b11",
"entry_digest": "18c9720aa0cd159e91318e72534c3d26999a24b47e942437f5f71ebf54b0bdb4",
"owners": [
"@exact:delivery"
]
},
{
"path": "README.md",
"kind": "file",
"mode": 33188,
"payload_digest": "289ab300914df33a650a5bcea39fa117ec6faa195ddbc21898aa76f6febb18e8",
"entry_digest": "32e5314496d86fc7895ae5b3cd036bea6f9be2a62df28e49f63007ceb1fb6b11",
"owners": [
"@exact:delivery"
]
},
{
"path": "action.yml",
"kind": "file",
"mode": 33188,
"payload_digest": "4d02a6581c053618af546163be6f382529717af1bc8021551fde2ba1e2789224",
"entry_digest": "ab41aee2dce9827ca24b764d0755fc319b98ec6f1cd30f418e42441ec39c4731",
"owners": [
"@exact:delivery"
]
}
]
},
"passed": true,
"commands": [
{
"command": "fledge lanes run verify-native",
"success": true,
"exit_code": 0
}
],
"requirement_ids": []
},
"stale_acceptance_input_digest": "32c7dddda1effbe78b0258768b9dea3ebce4fba92dcbe256af1cdd45f6719fe7",
"current_acceptance_input_digest": "3c9258d80c731e9b7381238fd82458164bba50b77180afe366a72e4f6c2ff2d2"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
id: CHG-0008-add-root-level-action-yml-github-action-for-installing-fledge-in-ci
state: accepted
type: feature
base_commit: 6eb7a3ea595c949f4bc0078c0738508d800356b3
---

# Add root-level action.yml GitHub Action for installing fledge in CI

## Intent

Add root-level action.yml GitHub Action for installing fledge in CI

## Affected Canonical Specs

- None

## Acceptance Criteria

- uses: CorvidLabs/fledge@v1 with version: v1.7.2 installs fledge on Linux and macOS runners and makes zero GitHub API calls; version: latest resolves via an authenticated API call; a corrupted download fails the checksum-verification step; Windows runners fail with a readable error instead of a 404 mid-download; the new exercising workflow passes on ubuntu-latest and macos-latest for both a pinned tag and latest; fledge lanes run check passes.

## No-spec Rationale

No canonical spec module governs this: .specsync/config.toml scans only source_dirs [src, templates], and the closest existing specs (specs/release for the fledge release command internals, specs/github for fledge's own GitHub API helper module) do not cover the repo's own CI/distribution surface. Only action.yml, a new workflow file, README.md, and CONTRIBUTING.md change; no src/ or templates/ files.
Loading
Loading