Skip to content
Open
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
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,34 @@ jobs:
toolchain: stable
- name: Run performance benchmark
run: './scripts/benchmark.sh --threshold 60 zsh rprompt'
dependency_review:
if: github.event_name == 'pull_request'
name: Dependency Review
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Dependency Review
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294
trivy:
name: Filesystem and Dependency Vulnerability Scan
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout Code
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803
with:
persist-credentials: 'false'
- name: Filesystem and Dependency Vulnerability Scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
scan-type: fs
scanners: vuln
vuln-type: os,library
severity: HIGH,CRITICAL
ignore-unfixed: 'false'
exit-code: '1'
draft_release:
needs:
- build
Expand Down
37 changes: 37 additions & 0 deletions crates/forge_ci/src/workflows/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,41 @@ pub fn generate_ci_workflow() {
.run("./scripts/benchmark.sh --threshold 60 zsh rprompt"),
);

let dependency_review_job = Job::new("Dependency Review")
.cond(Expression::new("github.event_name == 'pull_request'"))
.permissions(Permissions::default().contents(Level::Read))
.add_step(Step::new("Dependency Review").uses(
"actions",
"dependency-review-action",
"a1d282b36b6f3519aa1f3fc636f609c47dddb294",
));

let trivy_job = Job::new("Filesystem and Dependency Vulnerability Scan")
.permissions(Permissions::default().contents(Level::Read))
.add_step(
Step::new("Checkout Code")
.uses(
"actions",
"checkout",
"d23441a48e516b6c34aea4fa41551a30e30af803",
)
.with(("persist-credentials", "false")),
)
.add_step(
Step::new("Filesystem and Dependency Vulnerability Scan")
.uses(
"aquasecurity",
"trivy-action",
"ed142fd0673e97e23eac54620cfb913e5ce36c25",
)
.add_with(("scan-type", "fs"))
.add_with(("scanners", "vuln"))
.add_with(("vuln-type", "os,library"))
.add_with(("severity", "HIGH,CRITICAL"))
.add_with(("ignore-unfixed", "false"))
.add_with(("exit-code", "1")),
);

let draft_release_job = jobs::create_draft_release_job("build");
let draft_release_pr_job = jobs::create_draft_release_pr_job();
let events = Event::default()
Expand Down Expand Up @@ -73,6 +108,8 @@ pub fn generate_ci_workflow() {
.add_env(("OPENROUTER_API_KEY", "${{secrets.OPENROUTER_API_KEY}}"))
.add_job("build", build_job)
.add_job("zsh_rprompt_perf", perf_test_job)
.add_job("dependency_review", dependency_review_job)
.add_job("trivy", trivy_job)
.add_job("draft_release", draft_release_job)
.add_job("draft_release_pr", draft_release_pr_job)
.add_job("build_release", build_release_job)
Expand Down
25 changes: 25 additions & 0 deletions crates/forge_ci/tests/ci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ fn generate() {
workflow::generate_ci_workflow();
}

#[test]
fn generated_ci_preserves_blocking_pr_security_scans() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(2)
.expect("workspace root");
let workflow = std::fs::read_to_string(root.join(".github/workflows/ci.yml"))
.expect("generated ci workflow is readable");

assert!(workflow.contains("dependency_review:"));
assert!(workflow.contains("Dependency Review"));
assert!(workflow
.contains("actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294"));
assert!(workflow.contains("if: github.event_name == 'pull_request'"));
assert!(workflow.contains("trivy:"));
assert!(workflow.contains("Filesystem and Dependency Vulnerability Scan"));
assert!(workflow.contains("aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25"));
assert!(workflow.contains("persist-credentials: 'false'"));
assert!(workflow.contains("scan-type: fs"));
assert!(workflow.contains("scanners: vuln"));
assert!(workflow.contains("exit-code: '1'"));
assert!(workflow.ends_with('\n'));
assert!(workflow.lines().all(|line| line.trim_end() == line));
}

#[test]
fn test_release_drafter() {
workflow::generate_release_drafter_workflow();
Expand Down
Loading