Skip to content
Merged
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
100 changes: 100 additions & 0 deletions .github/workflows/multiversion-cycle-e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: multiversion circular dependency e2e

on:
push:
branches:
- feat/den-3488-multiversion-cycle-e2e
pull_request:
paths:
- tests/multiversion_cycle_contract.rs
- .github/workflows/multiversion-cycle-e2e.yml
- MULTIVERSION_CYCLE_E2E.md
- product-source-pin.json

permissions:
contents: read

concurrency:
group: multiversion-cycle-e2e-${{ github.ref }}
cancel-in-progress: true

jobs:
independent-contract:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30
with:
components: rustfmt
- name: Format contract test
run: rustfmt --edition 2024 --check tests/multiversion_cycle_contract.rs
- name: Compile with warnings denied
run: rustc --edition 2024 -D warnings --test tests/multiversion_cycle_contract.rs -o /tmp/multiversion-cycle-contract
- name: Run exact-node and real-symlink tests
run: /tmp/multiversion-cycle-contract --nocapture

product-integration:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
persist-credentials: false
- name: Read immutable product source pin
id: pin
shell: bash
run: |
python3 - <<'PY' >> "$GITHUB_OUTPUT"
import json
pin = json.load(open("product-source-pin.json"))
sha = pin["zed-pkg/zed-cli"]
if len(sha) != 40:
raise SystemExit("product SHA must contain exactly 40 hexadecimal characters")
print(f"sha={sha}")
print(f"ready={str(bool(pin['ready'])).lower()}")
PY
- name: Explain staged product validation
if: steps.pin.outputs.ready != 'true'
run: echo "Product integration is staged until the exact-graph branch has assembled and passed its in-repository suite."
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
if: steps.pin.outputs.ready == 'true'
with:
repository: zed-pkg/zed-cli
ref: ${{ steps.pin.outputs.sha }}
path: product/zed-cli
persist-credentials: false
- uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30
if: steps.pin.outputs.ready == 'true'
with:
components: rustfmt, clippy
- name: Verify immutable checkout
if: steps.pin.outputs.ready == 'true'
working-directory: product/zed-cli
shell: bash
run: test "$(git rev-parse HEAD)" = "${{ steps.pin.outputs.sha }}"
- name: Run executable multiversion cycle tests
if: steps.pin.outputs.ready == 'true'
working-directory: product/zed-cli
run: cargo test --locked --test versioned_dependency_cycles -- --nocapture
- name: Run exact-node unit tests
if: steps.pin.outputs.ready == 'true'
working-directory: product/zed-cli
run: cargo test --locked --lib versioned_graph -- --nocapture
- name: Check product formatting
if: steps.pin.outputs.ready == 'true'
working-directory: product/zed-cli
run: cargo fmt --all -- --check
- name: Lint exact graph code
if: steps.pin.outputs.ready == 'true'
working-directory: product/zed-cli
# The three allowed lints are current product-base failures proven by
# the product PR's pre-review validation. Every other warning is denied.
run: |
cargo clippy --locked --all-targets -- \
-D warnings \
-A clippy::large-enum-variant \
-A clippy::too-many-arguments \
-A clippy::type-complexity
39 changes: 39 additions & 0 deletions MULTIVERSION_CYCLE_E2E.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# DEN-3488 multiversion circular dependency E2E

This repository independently checks the exact dependency graph:

```text
A@1 -> B@1 -> A@2 -> B@0 -> A@2
```

The contract test is intentionally implemented in standalone Rust with no
third-party dependencies. It validates behavior independently of the product
resolver implementation.

## Required invariants

1. Node identity includes registry, organization, package name, and exact
version. `A@1` and `A@2` are distinct nodes even though they share the same
package coordinate.
2. Traversal terminates after four exact nodes and recognizes only the closing
`B@0 -> A@2` edge as the back-edge.
3. The materialization plan contains one consumer root link plus one link per
dependency edge. It does not create recursively nested package copies.
4. A real Unix filesystem materialization has exactly four canonical node
directories, and the closing edge is a symlink to the existing canonical
`A@2` node.
5. Applying the same plan twice is idempotent and preserves all link targets.
6. Diagnostics include exact versions, the closing edge, the selected symlink
strategy, and an explicit statement that recursive copying stopped.
7. Missing exact nodes fail validation before any materialization plan is
accepted.

## Product integration

`product-source-pin.json` is an immutable source pin for the corresponding
`zed-pkg/zed-cli` exact-graph implementation. The product job remains staged
until `ready` is set to `true` after the product branch has assembled and passed
its own tests. Once enabled, CI checks out that exact commit and reruns the
public executable cycle tests, exact-node unit tests, formatting, and Clippy.

The pin is never replaced with a branch name or floating tag.
6 changes: 6 additions & 0 deletions product-source-pin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"schemaVersion": 1,
"ready": true,
"zed-pkg/zed-cli": "8c0537e404f424cb648bede22db4334e8c3afca2",
"note": "Immutable product head for zed-pkg/zed-cli#315."
}
Loading
Loading