diff --git a/campaigns/TEMPLATE-DRIFT-CAMPAIGN.adoc b/campaigns/TEMPLATE-DRIFT-CAMPAIGN.adoc index 60db62c2..e82d0017 100644 --- a/campaigns/TEMPLATE-DRIFT-CAMPAIGN.adoc +++ b/campaigns/TEMPLATE-DRIFT-CAMPAIGN.adoc @@ -34,8 +34,11 @@ No rule in `AGENTIC.a2ml` assigns these recipes; that grant is the owner's. | `workflow-linter.yml` with the rule `head -1 "$file" \| grep -q "^# SPDX-License-Identifier:"`. The tool `gh actions-lock` writes its comment on line 1, so each lock run makes each managed workflow fail the lint. + Also a `workflow-linter.yml` with the first form of the template rule, + which stops only at a line in column 1 (`/^[^#[:space:]]/`). A workflow + with an indented body then passes with a licence line after the body. | The rule of the template: the licence line can be at any position in the - leading comment block. + leading comment block, and the block ends at the first line of the body. | `recipe-sonarqube-token-guard` | `fix-sonarqube-token-guard.sh` @@ -73,6 +76,9 @@ Each recipe was also run on the files of `system-et` at `main` (`04a8b6e`): * SPDX rule: the step is identical to the step of the template branch (`rsr-template-repo` pull request 323, `915acb2`). That pull request makes the rule stop at an indented workflow body also. +* SPDX rule, first form of the template rule: run on the linter of + `system-et` at `main` (`bbe1d13`), which has that form. 1 line changes, and + the step is identical to the step of the template at `main` (`0208563`). * Token guard: the job is identical to the job in pull request 92 (`9f529ef`). The guard step is identical to the guard step of the template branch (`rsr-template-repo` pull request 321, `806dac0`). @@ -102,10 +108,10 @@ and `fix-lock-self-sha-refs.sh` already cover these. inactive file (`e2e.yml.template`). * The token guard recipe edits only the shape of the old template. It does not rewrite a workflow that a person changed. -* The SPDX recipe has 1 target: the `head -1` rule. A linter that has the - first form of the template rule (the form before `rsr-template-repo` pull - request 323, for example in `system-et`) is not a target, and keeps that - form. +* The SPDX recipe has 2 targets: the `head -1` rule, and the first form of + the template rule (the form before `rsr-template-repo` pull request 323, + for example in `system-et`). A linter with any other rule is not a target, + and keeps its rule. * The number of repositories with each target is not known. No estate scan was made. diff --git a/scripts/fix-workflow-linter-spdx-rule.sh b/scripts/fix-workflow-linter-spdx-rule.sh index 7ec4113a..c479eff5 100755 --- a/scripts/fix-workflow-linter-spdx-rule.sh +++ b/scripts/fix-workflow-linter-spdx-rule.sh @@ -3,18 +3,30 @@ # # fix-workflow-linter-spdx-rule.sh: accept the SPDX line in the leading comment block # -# Older copies of the estate template have this rule in -# .github/workflows/workflow-linter.yml: +# Older copies of the estate template have 1 of 2 rules in +# .github/workflows/workflow-linter.yml. +# +# Form 1 reads line 1 only: # # if ! head -1 "$file" | grep -q "^# SPDX-License-Identifier:"; then # # The tool gh actions-lock writes its own comment on line 1 of each workflow # that it manages. Each lock run thus makes every managed workflow fail the -# lint ("missing SPDX header"). The current template (rsr-template-repo) -# accepts the licence line at any position in the leading comment block. -# This recipe replaces the old rule with the rule of the template. +# lint ("missing SPDX header"). +# +# Form 2 is the first template rule that reads the leading comment block: +# +# if ! awk '... /^[^#[:space:]]/ { exit } ...' "$file"; then +# +# It stops only at a line that starts in column 1. A workflow with an +# indented body thus passes with a licence line after the body +# (rsr-template-repo pull request 323). +# +# The current template (rsr-template-repo) accepts the licence line at any +# position in the leading comment block, and stops at the first line of the +# body. This recipe replaces each form with the rule of the template. # -# Only the exact old rule is a target. A linter with a different rule (for +# Only the 2 exact forms are targets. A linter with a different rule (for # example `head -5`) is not changed. # # Idempotent: a file that has the new rule is not changed. @@ -27,7 +39,23 @@ set -euo pipefail REL=".github/workflows/workflow-linter.yml" OLD_RULE='^[[:space:]]*if ! head -1 "\$[A-Za-z_][A-Za-z0-9_]*" \| grep -q "\^# SPDX-License-Identifier:"; then[[:space:]]*$' +OLD_AWK_RULE='/^# SPDX-License-Identifier:/ { found=1 } /^[^#[:space:]]/ { exit } END { exit !found }' NEW_RULE='/^# SPDX-License-Identifier:/ { found=1 } /^[[:space:]]*[^#[:space:]]/ { exit } END { exit !found }' +export OLD_AWK_RULE NEW_RULE + +# awk function: the position of form 2 in a line, or 0. A line is a target +# only when the whole line is `if ! awk '