From 6ceaedb07e73a806c50c4b3dca4b545250008d81 Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Mon, 18 May 2026 12:14:14 -0700 Subject: [PATCH] test: guard artifact retention in org workflows --- .../codex-structured-pr-review.yml | 1 + .github/workflows/pysa.yml | 1 + test/workflow_pr_ref_guard_test.rb | 46 ++++++++++++++++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/.github/workflow-templates/codex-structured-pr-review.yml b/.github/workflow-templates/codex-structured-pr-review.yml index 0afa3d0..2f159f2 100644 --- a/.github/workflow-templates/codex-structured-pr-review.yml +++ b/.github/workflow-templates/codex-structured-pr-review.yml @@ -139,3 +139,4 @@ jobs: codex-structured-review-prompt.md codex-structured-review.json if-no-files-found: ignore + retention-days: 7 diff --git a/.github/workflows/pysa.yml b/.github/workflows/pysa.yml index 9f291e4..7322a13 100644 --- a/.github/workflows/pysa.yml +++ b/.github/workflows/pysa.yml @@ -128,3 +128,4 @@ jobs: ${{ inputs.working_directory }}/pysa-output.txt ${{ inputs.working_directory }}/pysa-results/** if-no-files-found: ignore + retention-days: 7 diff --git a/test/workflow_pr_ref_guard_test.rb b/test/workflow_pr_ref_guard_test.rb index 2f89cea..212f976 100644 --- a/test/workflow_pr_ref_guard_test.rb +++ b/test/workflow_pr_ref_guard_test.rb @@ -1,20 +1,16 @@ # frozen_string_literal: true require "minitest/autorun" +require "yaml" class WorkflowPrRefGuardTest < Minitest::Test def test_review_workflows_do_not_depend_on_synthetic_pull_request_merge_refs - root = File.expand_path("..", __dir__) - workflow_paths = Dir.glob( - File.join(root, ".github", "{workflows,workflow-templates}", "*.{yml,yaml}") - ).sort - offenders = [] workflow_paths.each do |path| File.readlines(path, chomp: true).each_with_index do |line, index| next unless line.match?(%r{refs/pull/.*/merge}) - offenders << "#{path.delete_prefix("#{root}/")}:#{index + 1}: #{line.strip}" + offenders << "#{relative_path(path)}:#{index + 1}: #{line.strip}" end end @@ -25,4 +21,42 @@ def test_review_workflows_do_not_depend_on_synthetic_pull_request_merge_refs "#{offenders.join("\n")}" ) end + + def test_upload_artifact_steps_set_retention_days + offenders = [] + workflow_paths.each do |path| + data = YAML.safe_load(File.read(path), aliases: true) || {} + jobs = data.fetch("jobs", {}) || {} + jobs.each do |job_name, job| + Array(job && job["steps"]).each_with_index do |step, index| + next unless step.is_a?(Hash) && step["uses"].to_s.include?("actions/upload-artifact") + + with = step["with"].is_a?(Hash) ? step["with"] : {} + next if with.key?("retention-days") + + offenders << "#{relative_path(path)} #{job_name} step #{index + 1}" + end + end + end + + assert_empty( + offenders, + "Every upload-artifact step must set retention-days so diagnostic artifacts do not silently keep the repo default.\n" \ + "#{offenders.join("\n")}" + ) + end + + private + + def root + File.expand_path("..", __dir__) + end + + def workflow_paths + Dir.glob(File.join(root, ".github", "{workflows,workflow-templates}", "*.{yml,yaml}")).sort + end + + def relative_path(path) + path.delete_prefix("#{root}/") + end end