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
5 changes: 0 additions & 5 deletions src/compile/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,11 +465,6 @@ pub const AWF_VERSION: &str = "0.23.1";
/// See: https://pkgs.dev.azure.com/msazuresphere/_packaging/Guardian1ESPTUpstreamOrgFeed/nuget/v3/index.json
pub const COPILOT_CLI_VERSION: &str = "1.0.6";

/// Version of the Agency CLI (agency.linux-x64) NuGet package to install in 1ES pipelines.
/// Update this when upgrading to a new Agency CLI release.
/// See: https://pkgs.dev.azure.com/msazuresphere/_packaging/Guardian1ESPTUpstreamOrgFeed/nuget/v3/index.json
pub const AGENCY_CLI_VERSION: &str = "2026.1.22.4";

/// Generate source path for the execute command.
///
/// Returns a path using `{{ workspace }}` as the base, which gets resolved
Expand Down
5 changes: 3 additions & 2 deletions src/compile/onees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::path::Path;

use super::Compiler;
use super::common::{
self, AGENCY_CLI_VERSION, AWF_VERSION, DEFAULT_POOL, compute_effective_workspace, generate_copilot_params,
self, AWF_VERSION, COPILOT_CLI_VERSION, DEFAULT_POOL, compute_effective_workspace, generate_copilot_params,
generate_acquire_ado_token, generate_checkout_self, generate_checkout_steps,
generate_ci_trigger, generate_copilot_ado_env, generate_executor_ado_env,
generate_pipeline_path, generate_pipeline_resources, generate_pr_trigger,
Expand Down Expand Up @@ -139,7 +139,7 @@ displayName: "Finalize""#,
("{{ compiler_version }}", compiler_version),
// No-op for 1ES (template doesn't use AWF), but included for forward-compatibility
("{{ firewall_version }}", AWF_VERSION),
("{{ agency_version }}", AGENCY_CLI_VERSION),
("{{ copilot_version }}", COPILOT_CLI_VERSION),
("{{ pool }}", &pool),
("{{ schedule }}", &schedule),
("{{ pr_trigger }}", &pr_trigger),
Expand All @@ -163,6 +163,7 @@ displayName: "Finalize""#,
("{{ source_path }}", &source_path),
("{{ pipeline_path }}", &pipeline_path),
("{{ working_directory }}", &working_directory),
("{{ workspace }}", &working_directory),
("{{ agency_params }}", &agency_params),
("{{ acquire_ado_token }}", &acquire_read_token),
("{{ copilot_ado_env }}", &copilot_ado_env),
Expand Down
10 changes: 5 additions & 5 deletions templates/1es-base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,15 @@ extends:
displayName: "Authenticate NuGet Feed"

- task: NuGetCommand@2
displayName: "Install Agency CLI"
displayName: "Install Copilot CLI"
inputs:
command: 'custom'
arguments: 'install agency.linux-x64 -Source "https://pkgs.dev.azure.com/msazuresphere/_packaging/Guardian1ESPTUpstreamOrgFeed/nuget/v3/index.json" -Version {{ agency_version }} -OutputDirectory $(Agent.TempDirectory)/tools -ExcludeVersion -NonInteractive'
arguments: 'install Microsoft.Copilot.CLI.linux-x64 -Source "https://pkgs.dev.azure.com/msazuresphere/_packaging/Guardian1ESPTUpstreamOrgFeed/nuget/v3/index.json" -Version {{ copilot_version }} -OutputDirectory $(Agent.TempDirectory)/tools -ExcludeVersion -NonInteractive'

- bash: |
ls -la "$(Agent.TempDirectory)/tools"
echo "##vso[task.prependpath]$(Agent.TempDirectory)/tools/agency.linux-x64"
displayName: Add agency to PATH
echo "##vso[task.prependpath]$(Agent.TempDirectory)/tools/Microsoft.Copilot.CLI.linux-x64"
displayName: Add copilot to PATH

- bash: |
COMPILER_VERSION="{{ compiler_version }}"
Expand Down Expand Up @@ -230,7 +230,7 @@ extends:
THREAT_OUTPUT_FILE="$(Agent.TempDirectory)/threat-analysis-output.txt"

# Use $(cat file) like gh-aw does - the command is executed directly, not via a variable
agency copilot --prompt "$(cat $(Agent.TempDirectory)/threat-analysis-prompt.md)" {{ agency_params }} > "$THREAT_OUTPUT_FILE" 2>&1
copilot --prompt "$(cat $(Agent.TempDirectory)/threat-analysis-prompt.md)" {{ agency_params }} > "$THREAT_OUTPUT_FILE" 2>&1
AGENT_EXIT_CODE=$?

echo "=== Threat Analysis Output (sanitized) ==="
Expand Down
72 changes: 72 additions & 0 deletions tests/compiler_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,3 +784,75 @@ Do something.

let _ = fs::remove_dir_all(&temp_dir);
}

/// Test that the 1ES fixture compiles correctly with no unreplaced markers
/// and uses Copilot CLI (not Agency CLI) in custom jobs
#[test]
fn test_1es_compiled_output_no_unreplaced_markers() {
let temp_dir = std::env::temp_dir().join(format!(
"agentic-pipeline-1es-markers-{}",
std::process::id()
));
fs::create_dir_all(&temp_dir).expect("Failed to create temp directory");

let fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("fixtures")
.join("1es-test-agent.md");

let output_path = temp_dir.join("1es-test-agent.yml");

// Run the compiler binary
let binary_path = PathBuf::from(env!("CARGO_BIN_EXE_ado-aw"));
let output = std::process::Command::new(&binary_path)
.args([
"compile",
fixture_path.to_str().unwrap(),
"-o",
output_path.to_str().unwrap(),
])
.output()
.expect("Failed to run compiler");

assert!(
output.status.success(),
"1ES compiler should succeed: {}",
String::from_utf8_lossy(&output.stderr)
);
assert!(output_path.exists(), "Compiled 1ES YAML should exist");

let compiled = fs::read_to_string(&output_path).expect("Should read compiled YAML");

// Verify no unreplaced {{ markers }} remain (excluding ${{ }} which are ADO expressions)
for line in compiled.lines() {
let stripped = line.replace("${{", "");
assert!(
!stripped.contains("{{ "),
"1ES compiled output should not contain unreplaced marker: {}",
line.trim()
);
}

// Verify the compiler version was correctly substituted
let version = env!("CARGO_PKG_VERSION");
assert!(
compiled.contains(version),
"1ES compiled output should contain compiler version {version}"
);

// Verify 1ES template uses Copilot CLI, not Agency CLI
assert!(
compiled.contains("Microsoft.Copilot.CLI.linux-x64"),
"1ES template should install Copilot CLI"
);
assert!(
!compiled.contains("install agency.linux-x64"),
"1ES template should not install Agency CLI"
);
assert!(
!compiled.contains("agency copilot"),
"1ES template should not invoke 'agency copilot' command"
);

let _ = fs::remove_dir_all(&temp_dir);
}
Loading