1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""Hold the CodeScene uploader to its approved pin and inputs.
At the approved pin the uploader treats its committed `cli-manifest.json`
as the trust anchor for the cs-coverage archive, and it rejects a
non-empty `installer-checksum` outright. So no workflow passes that
input, none references the `CODESCENE_CLI_SHA256` variable that fed it,
every uploader step is pinned to the one approved SHA, and the dispatch
workflow that refreshed the variable stays deleted.
Every rule reads the workflows as `workflow_reader` parses them, so a
commented-out step or input is not a step or an input, and the owner and
repository in a `uses:` value are matched without regard to case, as
GitHub resolves them.
"""
#: The one uploader revision a workflow may pin.
: =
#: The input the uploader rejects at the approved pin, and the variable
#: whose only consumer it was, both folded.
: =
#: The dispatch workflow that refreshed the variable, folded.
: =
#: What an empty reading says, so a test can name it.
: =
r"""Return each active uploader step's ref, with the workflow holding it.
Returns
-------
list[tuple[str, str]]
The workflow path and the text after the step's first `@`, which
is empty when the step names no ref.
Examples
--------
>>> text = "on: push\njobs: {j: {steps: [{uses: Leynos/Shared-Actions/"
>>> text += ".github/actions/upload-codescene-coverage@v1}]}}\n"
>>> uploader_pins([Workflow.parse("p.yml", text)])
[('p.yml', 'v1')]
"""
return
r"""Return each uploader step pinned anywhere but the approved SHA.
Returns
-------
list[str]
One message per offending step, or one saying no uploader step
was found, since an empty reading would pass over anything.
Examples
--------
>>> pin_faults([Workflow.parse("p.yml", "on: push\njobs: {}\n")])
['no workflow step calls the CodeScene uploader']
"""
=
return
return
r"""Return the workflows whose parsed keys or values mention `name`.
Comments are not parsed, so a commented-out input is no mention.
Returns
-------
list[str]
The paths of the workflows mentioning `name`, case-folded.
Examples
--------
>>> text = "on: push\n# installer-checksum: x\njobs: {}\n"
>>> deprecated_mentions([Workflow.parse("p.yml", text)], "installer-checksum")
[]
"""
return
r"""Return any workflow named as the deleted refresh dispatch.
Returns
-------
list[str]
The matching workflow paths, compared case-folded.
Examples
--------
>>> flow = Workflow.parse(".github/workflows/Get-CodeScene-SHA.yml", "on: push\n")
>>> refresh_workflows([flow])
['.github/workflows/Get-CodeScene-SHA.yml']
"""
return