diff --git a/.github/workflows/copilot-setup-steps.yaml b/.github/workflows/copilot-setup-steps.yaml new file mode 100644 index 0000000000..662b6e613f --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yaml @@ -0,0 +1,76 @@ +############################## +# THIS FILE IS AUTOGENERATED # +# DO NOT MANUALLY EDIT # +############################## +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# GitHub Copilot setup steps for OpenVMM development environment +# Generated by flowey_hvlite - DO NOT EDIT MANUALLY + +name: "Copilot Setup Steps" + +# Automatically run the setup steps when they are changed to allow for easy validation, and +# allow manual testing through the repository's "Actions" tab +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yaml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yaml + +jobs: + # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. + copilot-setup-steps: + runs-on: ubuntu-latest + + # Set the permissions to the lowest permissions possible needed for your steps. + # Copilot will be given its own token for its operations. + permissions: + # If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete. + contents: read + + steps: + - name: Install Rust with required targets + run: | + # Install Rust using rustup (version managed by flowey) + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain=1.88.0 + source ~/.cargo/env + + # Install targets for the host architecture + ARCH=$(uname -m) + if [ "$ARCH" = "x86_64" ]; then + rustup target add x86_64-unknown-linux-musl + elif [ "$ARCH" = "aarch64" ]; then + rustup target add aarch64-unknown-linux-musl + fi + + - name: Install system dependencies + run: | + # Update package lists with retry logic (from CI pipelines) + set -x + i=0; while [ $i -lt 5 ] && ! sudo apt-get update; do let "i=i+1"; sleep 1; done; + + # Install build dependencies required for OpenVMM + sudo apt-get -o DPkg::Lock::Timeout=60 install -y \ + binutils \ + build-essential \ + gcc \ + gcc-aarch64-linux-gnu \ + libssl-dev \ + pkg-config + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Restore OpenVMM build dependencies + run: | + # Restore external dependencies required for building OpenVMM + # This includes protoc (Protocol Buffers compiler), mu_msvm UEFI firmware, + # test Linux kernels, and other build artifacts + cargo xflowey restore-packages + + # Install cargo-nextest for running unit tests (version managed by flowey) + cargo install cargo-nextest --version 0.9.96 --locked diff --git a/flowey/flowey_hvlite/src/pipelines/copilot_setup_generator.rs b/flowey/flowey_hvlite/src/pipelines/copilot_setup_generator.rs new file mode 100644 index 0000000000..edd2bd081b --- /dev/null +++ b/flowey/flowey_hvlite/src/pipelines/copilot_setup_generator.rs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +use anyhow::Result; + +/// Generate copilot-setup-steps.yml for GitHub Copilot Coding Agent +#[derive(clap::Args)] +pub struct CopilotSetupGeneratorCli {} + +impl CopilotSetupGeneratorCli { + pub fn run(self, repo_root: &std::path::Path) -> Result<()> { + let output_file = repo_root.join(".github/workflows/copilot-setup-steps.yaml"); + + // Ensure the output directory exists + if let Some(parent) = output_file.parent() { + std::fs::create_dir_all(parent)?; + } + + let content = generate_copilot_setup_steps(); + + std::fs::write(&output_file, content)?; + + println!("Generated .github/workflows/copilot-setup-steps.yaml"); + Ok(()) + } +} + +fn generate_copilot_setup_steps() -> String { + crate::pipelines_shared::copilot_setup_steps_template::get_template() +} diff --git a/flowey/flowey_hvlite/src/pipelines/mod.rs b/flowey/flowey_hvlite/src/pipelines/mod.rs index 54865221e2..2117b979bd 100644 --- a/flowey/flowey_hvlite/src/pipelines/mod.rs +++ b/flowey/flowey_hvlite/src/pipelines/mod.rs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +use copilot_setup_generator::CopilotSetupGeneratorCli; use flowey::pipeline::prelude::*; use restore_packages::RestorePackagesCli; use vmm_tests::VmmTestsCli; @@ -8,6 +9,7 @@ use vmm_tests::VmmTestsCli; pub mod build_docs; pub mod build_igvm; pub mod checkin_gates; +pub mod copilot_setup_generator; pub mod custom_vmfirmwareigvm_dll; pub mod restore_packages; pub mod vmm_tests; @@ -29,6 +31,9 @@ pub enum OpenvmmPipelines { #[clap(subcommand)] Ci(OpenvmmPipelinesCi), + /// Generate copilot-setup-steps.yml file directly + CopilotSetupGenerator(CopilotSetupGeneratorCli), + /// Install tools needed to build OpenVMM RestorePackages(RestorePackagesCli), @@ -59,6 +64,11 @@ impl IntoPipeline for OpenvmmPipelines { OpenvmmPipelinesCi::CheckinGates(cmd) => cmd.into_pipeline(pipeline_hint), OpenvmmPipelinesCi::BuildDocs(cmd) => cmd.into_pipeline(pipeline_hint), }, + OpenvmmPipelines::CopilotSetupGenerator(cmd) => { + cmd.run(&crate::repo_root())?; + // Return empty pipeline since we've already done the work + Ok(Pipeline::new()) + } OpenvmmPipelines::RestorePackages(cmd) => cmd.into_pipeline(pipeline_hint), OpenvmmPipelines::VmmTests(cmd) => cmd.into_pipeline(pipeline_hint), } diff --git a/flowey/flowey_hvlite/src/pipelines_shared/copilot_setup_steps_template.rs b/flowey/flowey_hvlite/src/pipelines_shared/copilot_setup_steps_template.rs new file mode 100644 index 0000000000..0c33b29257 --- /dev/null +++ b/flowey/flowey_hvlite/src/pipelines_shared/copilot_setup_steps_template.rs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! See [`get_template`] + +/// Get our internal copilot setup steps template. +/// +/// This template provides the steps needed to set up the OpenVMM development +/// environment for GitHub Copilot's Coding Agent. +pub fn get_template() -> String { + let template = include_str!("copilot_setup_steps_template.yml").to_string(); + + template + .replace( + "{{RUSTUP_TOOLCHAIN}}", + flowey_lib_hvlite::_jobs::cfg_versions::RUSTUP_TOOLCHAIN, + ) + .replace( + "{{NEXTEST_VERSION}}", + flowey_lib_hvlite::_jobs::cfg_versions::NEXTEST, + ) +} diff --git a/flowey/flowey_hvlite/src/pipelines_shared/copilot_setup_steps_template.yml b/flowey/flowey_hvlite/src/pipelines_shared/copilot_setup_steps_template.yml new file mode 100644 index 0000000000..4663af0f8d --- /dev/null +++ b/flowey/flowey_hvlite/src/pipelines_shared/copilot_setup_steps_template.yml @@ -0,0 +1,76 @@ +############################## +# THIS FILE IS AUTOGENERATED # +# DO NOT MANUALLY EDIT # +############################## +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# GitHub Copilot setup steps for OpenVMM development environment +# Generated by flowey_hvlite - DO NOT EDIT MANUALLY + +name: "Copilot Setup Steps" + +# Automatically run the setup steps when they are changed to allow for easy validation, and +# allow manual testing through the repository's "Actions" tab +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yaml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yaml + +jobs: + # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. + copilot-setup-steps: + runs-on: ubuntu-latest + + # Set the permissions to the lowest permissions possible needed for your steps. + # Copilot will be given its own token for its operations. + permissions: + # If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete. + contents: read + + steps: + - name: Install Rust with required targets + run: | + # Install Rust using rustup (version managed by flowey) + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain={{RUSTUP_TOOLCHAIN}} + source ~/.cargo/env + + # Install targets for the host architecture + ARCH=$(uname -m) + if [ "$ARCH" = "x86_64" ]; then + rustup target add x86_64-unknown-linux-musl + elif [ "$ARCH" = "aarch64" ]; then + rustup target add aarch64-unknown-linux-musl + fi + + - name: Install system dependencies + run: | + # Update package lists with retry logic (from CI pipelines) + set -x + i=0; while [ $i -lt 5 ] && ! sudo apt-get update; do let "i=i+1"; sleep 1; done; + + # Install build dependencies required for OpenVMM + sudo apt-get -o DPkg::Lock::Timeout=60 install -y \ + binutils \ + build-essential \ + gcc \ + gcc-aarch64-linux-gnu \ + libssl-dev \ + pkg-config + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Restore OpenVMM build dependencies + run: | + # Restore external dependencies required for building OpenVMM + # This includes protoc (Protocol Buffers compiler), mu_msvm UEFI firmware, + # test Linux kernels, and other build artifacts + cargo xflowey restore-packages + + # Install cargo-nextest for running unit tests (version managed by flowey) + cargo install cargo-nextest --version {{NEXTEST_VERSION}} --locked diff --git a/flowey/flowey_hvlite/src/pipelines_shared/mod.rs b/flowey/flowey_hvlite/src/pipelines_shared/mod.rs index 7cdfce2dfc..ea624f09dd 100644 --- a/flowey/flowey_hvlite/src/pipelines_shared/mod.rs +++ b/flowey/flowey_hvlite/src/pipelines_shared/mod.rs @@ -4,5 +4,6 @@ //! Shared constants and helper functionality used across multiple pipelines. pub mod cfg_common_params; +pub mod copilot_setup_steps_template; pub mod gh_flowey_bootstrap_template; pub mod gh_pools;