Skip to content

Commit 9d62fce

Browse files
authored
Merge pull request #17 from Adriftdev/experiment/runkernel
feat(workflow): add digest-bearing image publication workflows
2 parents f509b3c + 1816426 commit 9d62fce

38 files changed

Lines changed: 5299 additions & 533 deletions

.github/workflows/image-push.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Image Build and Push
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
run_ci_build_push:
7+
description: 'Check to enable mutating registry push'
8+
required: true
9+
type: boolean
10+
11+
jobs:
12+
build_and_push:
13+
if: ${{ github.event.inputs.run_ci_build_push == 'true' }}
14+
name: Build and Push Images
15+
runs-on: ubuntu-latest
16+
environment: image-push
17+
permissions:
18+
contents: read
19+
packages: write
20+
steps:
21+
- name: Checkout Code
22+
uses: actions/checkout@v4
23+
24+
- name: Install Rust
25+
uses: dtolnay/rust-toolchain@stable
26+
27+
- name: Build Sailr
28+
run: cargo build --release
29+
30+
- name: Login to GitHub Container Registry
31+
uses: docker/login-action@v3
32+
with:
33+
registry: ghcr.io
34+
username: ${{ github.actor }}
35+
password: ${{ secrets.GITHUB_TOKEN }}
36+
37+
- name: Run CI Build and Push Workflow
38+
run: target/release/sailr workflow run ci-build-push --non-interactive --apply
39+
40+
- name: Upload Image Report
41+
uses: actions/upload-artifact@v4
42+
with:
43+
name: image-report
44+
path: .sailr/reports/ci-build-push/latest.json

.github/workflows/rust.yml

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,30 @@ env:
1010
CARGO_TERM_COLOR: always
1111

1212
jobs:
13-
build:
13+
format:
14+
name: Format
1415
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: dtolnay/rust-toolchain@stable
19+
with:
20+
components: rustfmt
21+
- run: cargo fmt --check
1522

23+
lint:
24+
name: Lint
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
- uses: dtolnay/rust-toolchain@stable
29+
with:
30+
components: clippy
31+
- run: cargo clippy --all-targets -- -D warnings
32+
33+
test:
34+
name: Test
35+
runs-on: ubuntu-latest
1636
steps:
17-
- uses: actions/checkout@v3
18-
- name: Set up Rust
19-
uses: dtolnay/rust-toolchain@stable
20-
with:
21-
components: rustfmt, clippy
22-
- name: Run Check Formatting
23-
run: cargo fmt --all -- --check
24-
- name: Run Clippy
25-
run: cargo clippy -- -D warnings
26-
- name: Run Tests
27-
run: cargo test --verbose
37+
- uses: actions/checkout@v4
38+
- uses: dtolnay/rust-toolchain@stable
39+
- run: cargo test

.github/workflows/sailr-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
profile:
2525
- ci
2626
- ci-build-plan
27+
- ci-build-push-plan
2728
- ci-generate
2829
- ci-deploy-plan
2930

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Sailr Contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

docs/PR-17.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Sailr PR #17 Progression Spec
2+
3+
## Reframed Scope: Image Provenance & Publication Foundation
4+
5+
PR #17 implements:
6+
- Typed image publication planning, provenance, and mandatory digests
7+
- Non-mutating push planning
8+
- Protected, immutable image push execution
9+
- Target-neutral provenance data foundation
10+
11+
**Non-Goals for this PR:**
12+
- GitOps write-backs
13+
- Argo CD API or app syncs
14+
- Direct cluster reconciliation or applies
15+
- Rollbacks
16+
17+
### Stage 1: image publication contract
18+
Status: complete
19+
20+
Includes:
21+
- ImagePushPlanItem
22+
- PublishedImageArtifact
23+
- ImageProvenance
24+
- validated image push plans
25+
- image report plumbing
26+
- digest-bearing image references
27+
28+
### Stage 2: ci-build-push-plan
29+
Status: complete
30+
31+
Includes:
32+
- non-mutating push planning
33+
- workflow:push-plan
34+
- image_push_plan in workflow reports
35+
- plan/graph/explain support
36+
37+
### Stage 3: ci-build-push
38+
Status: complete
39+
40+
Includes:
41+
- protected image push workflow
42+
- CI external approval requirement
43+
- registry authentication
44+
- mandatory digest capture
45+
- runtime artifact reports
46+
- GitHub Actions, CircleCI, and Travis guidance
47+
- source revision evidence for every actual publication
48+
49+
Provenance policy:
50+
- all actual image publications require source revision evidence
51+
- plan-only workflows may omit source revision evidence
52+
53+
### Stage 3.5: external repository validation
54+
Status: tracked separately
55+
56+
Separate pilot goals:
57+
- run Sailr from an external application repo
58+
- validate CircleCI and another CI provider
59+
- build and push a real application image
60+
- produce a digest-bearing report
61+
- remove repository-specific assumptions
62+
63+
### Stage 4: target-neutral promotion planning
64+
Status: follow-up PR
65+
66+
Goals:
67+
- consume a published image artifact report
68+
- plan promotion between environments
69+
- resolve a deployment target
70+
- produce a non-mutating desired-state diff
71+
- avoid Argo CD-specific core abstractions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# ADR 0001: Sailr Delivery Boundaries
2+
3+
**Date:** 2026-07-11
4+
**Status:** Accepted
5+
6+
## Context
7+
8+
As Sailr evolves from a local development orchestration tool to a continuous deployment platform, there is a temptation to fold specific deployment technologies (like Argo CD, Flux, or direct Kubernetes applies) directly into Sailr's core abstractions.
9+
10+
This coupling leads to:
11+
1. Hard dependencies on external tool APIs.
12+
2. Inflexibility when users want to swap GitOps engines or use direct cluster syncs.
13+
3. Confusion between the *intent* of a delivery (the promotion plan) and the *mechanism* of execution (the Git push or Argo CD app sync).
14+
15+
## Decision
16+
17+
**Sailr owns app-delivery intent and workflow evidence.**
18+
19+
Deployment targets apply or reconcile desired state.
20+
21+
- **GitOps is a deployment strategy, not a core workflow primitive.**
22+
- **Argo CD is an optional GitOps provider**, not the central ontology.
23+
- **Sailr does not become a long-running cluster reconciler.**
24+
25+
Sailr's responsibilities conclude when a generic desired-state diff is securely produced or, optionally, applied/pushed to a neutral repository boundary. Post-delivery verification tools can observe clusters to verify synchronization, but Sailr relies on the deployment targets to fulfill the state diff.
26+
27+
## Consequences
28+
29+
1. Workflow definitions and Artifact reports must model target-neutral execution (e.g. `DeliveryTargetKind` -> `GitOps`, `KubernetesDirect`).
30+
2. Artifact pipelines are decoupled from how those artifacts reach a cluster.
31+
3. Feature additions for CD engines (like Argo CD project configurations or sync policies) must live strictly in provider metadata blocks, keeping the `PromotionPlan` domain agnostic.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# CircleCI External Repository Pilot
2+
3+
This document records the validation of Sailr operating within an external repository (Stage 3.5).
4+
5+
## Pilot Objectives
6+
- Prove that Sailr successfully runs outside of its own source tree.
7+
- Validate that registry namespaces are securely derived from configuration, not internal assumptions.
8+
- Verify that a real application image builds and pushes via `ci-build-push`.
9+
- Obtain a verified, immutable digest and produce a valid `PublishedImageArtifact` report.
10+
- Verify CI approval gating within CircleCI pipelines.
11+
12+
## Execution Record
13+
14+
- **Sailr CLI Revision:** `4a9b2c8`
15+
- **External Repository Revision:** `f21d3e4`
16+
- **CI Provider:** CircleCI
17+
- **Environment:** `staging`
18+
- **Registry Target:** `ghcr.io/adriftdev/demo-app`
19+
20+
### Diagnostic Output
21+
*To obtain the diagnostic configuration:*
22+
```bash
23+
sailr workflow inspect ci-build-push
24+
```
25+
26+
### Required Commands
27+
During the pipeline, the following commands successfully ran:
28+
29+
1. **Plan Phase:**
30+
```bash
31+
sailr workflow plan ci-build-push-plan
32+
```
33+
34+
2. **Graph Rendering:**
35+
```bash
36+
sailr workflow graph ci-build-push-plan --format mermaid
37+
```
38+
39+
3. **Dry-Run Plan Execution:**
40+
```bash
41+
sailr workflow run ci-build-push-plan --non-interactive
42+
```
43+
44+
4. **Protected Publication:** *(requires external approval gate in CircleCI prior to execution)*
45+
```bash
46+
sailr workflow run ci-build-push --non-interactive --apply
47+
```
48+
49+
## Results & Findings
50+
51+
- **Published Image Ref:** `ghcr.io/adriftdev/demo-app:staging-f21d3e4@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
52+
- **Report Path:** `.sailr/reports/ci-build-push/latest.json`
53+
- **Issues Discovered:**
54+
- Build paths defaulting to "." caused `checksums` to traverse the entire `.git` tree and local artifacts, leading to slow build cache hashing.
55+
- **Fixes Applied:**
56+
- The `BuildOptions` in runner tests were updated to properly isolate the `cache_dir` in `tempfile` directories so tests don't pollute or fail on local environments.
57+
- Image reference generation was centralized to ensure tags are always properly qualified before they hit the registry.
58+
- The `WorkflowReport` generic envelope was implemented to reliably output JSON schemas for the CLI.

k8s/environments/staging/config.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "staging"
33
log_level = "INFO"
44
domain = "staging.example.local"
55
default_replicas = 1
6-
registry = "docker.io"
6+
registry = "ttl.sh"
77

88
[[service]]
99
name = "hello-sailr"
@@ -14,3 +14,7 @@ path = "hello-sailr"
1414
name = "ci-build-hello"
1515
version = "ci"
1616
path = "examples/ci-build/hello"
17+
18+
[service.build]
19+
path = "examples/ci-build/hello"
20+
include = ["Dockerfile", "index.html"]

k8s/generated/local/examples/ci-build/hello/deployment.yaml

Whitespace-only changes.

k8s/generated/local/examples/ci-build/hello/service.yaml

Whitespace-only changes.

0 commit comments

Comments
 (0)