@@ -17,7 +17,7 @@ pub struct ScanReport {
1717 pub outcome : ScanOutcome ,
1818}
1919
20- fn zizmor_command ( repo_path : & Path , config_path : & Path , github_token : & str ) -> Command {
20+ fn zizmor_command ( github_path : & Path , config_path : & Path , github_token : & str ) -> Command {
2121 let mut command = Command :: new ( "zizmor" ) ;
2222 command
2323 . env ( "ZIZMOR_GITHUB_TOKEN" , github_token)
@@ -27,7 +27,7 @@ fn zizmor_command(repo_path: &Path, config_path: &Path, github_token: &str) -> C
2727 . arg ( "pedantic" )
2828 // Fail on GitHub workflow syntax error.
2929 . arg ( "--strict-collection" )
30- . arg ( repo_path ) ;
30+ . arg ( github_path ) ;
3131 command
3232}
3333
@@ -55,12 +55,28 @@ pub(crate) fn sync_zizmor_config(crabwatch_dir: &Path) -> anyhow::Result<PathBuf
5555 Ok ( config_path)
5656}
5757
58+ fn root_github_path ( repo_path : & Path ) -> anyhow:: Result < Option < PathBuf > > {
59+ let github_path = repo_path. join ( ".github" ) ;
60+ let path = github_path
61+ . try_exists ( )
62+ . with_context ( || format ! ( "failed to inspect GitHub directory at {github_path:?}" ) ) ?
63+ . then_some ( github_path) ;
64+ Ok ( path)
65+ }
66+
5867pub async fn scan_workflows (
5968 repo_path : & Path ,
6069 config_path : & Path ,
6170 github_token : & str ,
6271) -> anyhow:: Result < ScanReport > {
63- let output = zizmor_command ( repo_path, config_path, github_token)
72+ let Some ( github_path) = root_github_path ( repo_path) ? else {
73+ return Ok ( ScanReport {
74+ output : "no workflows to scan" . to_string ( ) ,
75+ outcome : ScanOutcome :: NoWorkflows ,
76+ } ) ;
77+ } ;
78+
79+ let output = zizmor_command ( & github_path, config_path, github_token)
6480 . output ( )
6581 . await ;
6682
@@ -104,6 +120,25 @@ pub async fn scan_workflows(
104120mod tests {
105121 use super :: * ;
106122
123+ #[ tokio:: test]
124+ async fn nested_workflows_without_root_github_are_not_scanned ( ) {
125+ let repo = tempfile:: tempdir ( ) . unwrap ( ) ;
126+ let nested_workflows = repo. path ( ) . join ( "vendor/project/.github/workflows" ) ;
127+ std:: fs:: create_dir_all ( & nested_workflows) . unwrap ( ) ;
128+ std:: fs:: write (
129+ nested_workflows. join ( "publish.yml" ) ,
130+ "on: push\n jobs:\n publish:\n runs-on: ubuntu-latest\n steps:\n - run: echo hello\n " ,
131+ )
132+ . unwrap ( ) ;
133+ let config_dir = tempfile:: tempdir ( ) . unwrap ( ) ;
134+ let config_path = sync_zizmor_config ( config_dir. path ( ) ) . unwrap ( ) ;
135+
136+ let report = scan_workflows ( repo. path ( ) , & config_path, "" ) . await . unwrap ( ) ;
137+
138+ assert_eq ! ( report. outcome, ScanOutcome :: NoWorkflows ) ;
139+ assert_eq ! ( report. output, "no workflows to scan" ) ;
140+ }
141+
107142 #[ test]
108143 fn creates_config_and_keeps_identical_file ( ) {
109144 // The first sync should create the directory and bundled config from scratch.
0 commit comments