diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 50cc741be2..8acccae7b9 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -117,3 +117,28 @@ This project uses the **Rust 2024 edition** (`edition = "2024"` in root hand-edit them. Run `cargo xflowey regen` to regenerate. - **flowey nodes**: Use `flowey::shell_cmd!` and `rt.sh` inside flowey nodes — not `xshell::cmd!` or `xshell::Shell::new`. + +## Autonomous Agent Inner Loop + +When running as a coding agent (GitHub Copilot coding agent or similar), +follow this validation loop **before pushing each commit**. This covers +the common early CI failures (including the fmt + clippy checks from job0) +locally, avoiding slow push-and-wait cycles. + +1. **Identify modified packages.** For each file you changed, find the + crate's `Cargo.toml` and note the package name. +2. **Check compilation:** `cargo check -p ` — fast type-check. +3. **Clippy:** `cargo clippy --all-targets -p ` — lint. +4. **Doc:** `cargo doc --no-deps -p ` — catch doc errors. +5. **Unit tests:** `cargo nextest run -p ` — run the crate's + tests. If nextest is not installed, use `cargo test -p `. +6. **Formatting:** `cargo xtask fmt --fix` — run last, since earlier + fixes may introduce formatting changes. + +If any step fails, fix the issue and re-run from that step. Do not push +until all six steps pass. + +**Cost notes:** Steps 2–5 are scoped to the modified package (`-p`), +so they are fast even in this large workspace. Step 6 runs workspace-wide +but is also fast. The full cycle typically takes under 2 minutes for +a single-crate change. diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 0000000000..10cdace39f --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,41 @@ +name: "Copilot Setup Steps" + +# Validate the setup steps when they change, and allow manual testing. +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +jobs: + # This job name is required — the Copilot coding agent looks for it by name. + copilot-setup-steps: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v6 + + # Install the exact Rust toolchain used by CI. + - name: Install Rust toolchain + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ + | sh -s -- --default-toolchain=1.94.0 -y + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + + # Install cargo-nextest so the agent can run unit tests. + # Keep this version in sync with NEXTEST in + # flowey/flowey_lib_hvlite/src/_jobs/cfg_versions.rs + - name: Install cargo-nextest + run: | + curl -LsSf https://get.nexte.st/0.9.101/linux | tar zxf - -C "$HOME/.cargo/bin" + + # Restore protoc and other build dependencies via the canonical + # flowey pipeline. This compiles flowey_hvlite first, then downloads + # protoc, sysroots, firmware, and test kernels. + - name: Restore packages + run: cargo xflowey restore-packages --no-compat-igvm diff --git a/flowey/flowey_hvlite/src/pipelines/restore_packages.rs b/flowey/flowey_hvlite/src/pipelines/restore_packages.rs index 0bffe115d8..56d2f86568 100644 --- a/flowey/flowey_hvlite/src/pipelines/restore_packages.rs +++ b/flowey/flowey_hvlite/src/pipelines/restore_packages.rs @@ -12,6 +12,12 @@ pub struct RestorePackagesCli { /// /// If none are specified, defaults to just the current host architecture. arch: Vec, + + /// Skip downloading released OpenHCL IGVM files used for compatibility testing. + /// + /// This avoids the need for `gh` CLI authentication. + #[clap(long)] + no_compat_igvm: bool, } impl IntoPipeline for RestorePackagesCli { @@ -21,7 +27,11 @@ impl IntoPipeline for RestorePackagesCli { ); let mut pipeline = Pipeline::new(); - let (pub_last_release_igvm_files, _) = pipeline.new_artifact("last-release-igvm-files"); + let pub_last_release_igvm_files = if self.no_compat_igvm { + None + } else { + Some(pipeline.new_artifact("last-release-igvm-files").0) + }; let mut job = pipeline .new_job( FlowPlatform::host(backend_hint), @@ -59,7 +69,7 @@ impl IntoPipeline for RestorePackagesCli { |ctx| flowey_lib_hvlite::_jobs::local_restore_packages::Request { arches, done: ctx.new_done_handle(), - release_artifact: ctx.publish_artifact(pub_last_release_igvm_files), + release_artifact: pub_last_release_igvm_files.map(|a| ctx.publish_artifact(a)), }, ); job.finish(); diff --git a/flowey/flowey_lib_hvlite/src/_jobs/local_restore_packages.rs b/flowey/flowey_lib_hvlite/src/_jobs/local_restore_packages.rs index f8a2219a2e..d5b6389ad0 100644 --- a/flowey/flowey_lib_hvlite/src/_jobs/local_restore_packages.rs +++ b/flowey/flowey_lib_hvlite/src/_jobs/local_restore_packages.rs @@ -11,7 +11,8 @@ flowey_request! { pub struct Request{ pub arches: Vec, pub done: WriteVar, - pub release_artifact: ReadVar, + /// If `None`, skip downloading OpenHCL IGVM release files. + pub release_artifact: Option>, } } @@ -85,18 +86,20 @@ impl SimpleFlowNode for Node { } } - deps.push( - ctx.reqv( - |v| crate::init_openvmm_magicpath_release_openhcl_igvm::resolve::Request { - arch, - release_version: - crate::download_release_igvm_files_from_gh::OpenhclReleaseVersion::latest(), - release_artifact:release_artifact.clone(), - done: v, - }, - ) - .into_side_effect(), - ); + if let Some(release_artifact) = &release_artifact { + deps.push( + ctx.reqv( + |v| crate::init_openvmm_magicpath_release_openhcl_igvm::resolve::Request { + arch, + release_version: + crate::download_release_igvm_files_from_gh::OpenhclReleaseVersion::latest(), + release_artifact: release_artifact.clone(), + done: v, + }, + ) + .into_side_effect(), + ); + } } ctx.emit_side_effect_step(deps, [done]);