-
Notifications
You must be signed in to change notification settings - Fork 0
175 lines (162 loc) · 5.87 KB
/
validate.yml
File metadata and controls
175 lines (162 loc) · 5.87 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
name: validate
on:
pull_request:
paths:
- "packages/**"
- "schema/**"
push:
branches: [main]
paths:
- "packages/**"
- "schema/**"
# Fire the strict-schema job only after mirror-tarball has populated the
# freshly-merged null entries. See the strict-main job comment for details.
workflow_run:
workflows: ["mirror-tarball"]
types: [completed]
jobs:
schema:
name: JSONSchema validation
if: github.event_name != 'workflow_run'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install ajv-cli
run: npm install -g ajv-cli ajv-formats
- name: Validate every manifest against schema
run: |
set -euo pipefail
FAIL=0
for manifest in packages/*/manifest.json; do
echo "Validating $manifest"
ajv validate --spec=draft2020 -c ajv-formats -s schema/manifest.schema.json -d "$manifest" --strict=false || FAIL=1
done
exit $FAIL
strict-main:
name: Strict schema (tarball + sha256 required)
# Runs only after mirror-tarball completes on main. Merge PRs submit with
# null tarball/sha256; mirror-tarball populates them and pushes a backfill
# commit. That bot-push doesn't re-trigger push-driven workflows (default
# GITHUB_TOKEN behavior), so we use workflow_run to re-enter here and
# enforce that every version entry is fully materialized.
if: >-
github.event_name == 'workflow_run' &&
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Explicit main checkout — default on workflow_run triggers is the
# triggering workflow's head_sha (pre-mirror), which still has nulls.
ref: main
- uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install ajv-cli
run: npm install -g ajv-cli ajv-formats
- name: Validate every manifest against strict schema
run: |
set -euo pipefail
FAIL=0
for manifest in packages/*/manifest.json; do
echo "Strict-validating $manifest"
ajv validate --spec=draft2020 -c ajv-formats \
-s schema/manifest.strict.schema.json \
-d "$manifest" --strict=false || FAIL=1
done
exit $FAIL
structure:
name: Directory + name consistency
if: github.event_name != 'workflow_run'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check name matches directory
run: |
set -euo pipefail
FAIL=0
for manifest in packages/*/manifest.json; do
dir=$(basename "$(dirname "$manifest")")
name=$(jq -r .name "$manifest")
if [ "$dir" != "$name" ]; then
echo "MISMATCH: directory '$dir' but manifest.name '$name'"
FAIL=1
fi
done
exit $FAIL
- name: Check name uniqueness
run: |
set -euo pipefail
duplicates=$(jq -r .name packages/*/manifest.json | sort | uniq -d)
if [ -n "$duplicates" ]; then
echo "Duplicate names: $duplicates"
exit 1
fi
source-resolvable:
name: source.repo + sourceTag resolve on GitHub
if: github.event_name != 'workflow_run'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify each source.repo and its tags exist
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
FAIL=0
for manifest in packages/*/manifest.json; do
repo=$(jq -r .source.repo "$manifest")
echo "Checking $repo ..."
if ! gh repo view "$repo" >/dev/null 2>&1; then
echo "MISSING REPO: $repo"
FAIL=1
continue
fi
jq -r '.versions[].sourceTag' "$manifest" | while read -r tag; do
if ! gh api "repos/$repo/git/refs/tags/$tag" >/dev/null 2>&1; then
echo "MISSING TAG: $repo#$tag"
exit 1
fi
done || FAIL=1
done
exit $FAIL
content-safety:
name: File-type allowlist + size cap
if: github.event_name != 'workflow_run'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Clone each source tag & scan
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
ALLOWED='\.cfc$|\.cfm$|\.cfml$|\.md$|\.json$|\.js$|\.mjs$|\.ts$|\.css$|\.scss$|\.html$|\.txt$|\.sql$|\.yml$|\.yaml$|\.gitkeep$|LICENSE$|CHANGELOG$'
MAX_BYTES=$((10 * 1024 * 1024))
FAIL=0
for manifest in packages/*/manifest.json; do
repo=$(jq -r .source.repo "$manifest")
latest_tag=$(jq -r '.versions[-1].sourceTag' "$manifest")
echo "Scanning $repo@$latest_tag"
tmp=$(mktemp -d)
gh repo clone "$repo" "$tmp/src" -- --depth=1 --branch="$latest_tag"
# Size cap
size=$(du -sb "$tmp/src" --exclude=.git | awk '{print $1}')
if [ "$size" -gt "$MAX_BYTES" ]; then
echo "OVER CAP: $repo = $size bytes"
FAIL=1
fi
# File-type allowlist
disallowed=$(find "$tmp/src" -type f -not -path "*/.git/*" | grep -vE "$ALLOWED" || true)
if [ -n "$disallowed" ]; then
echo "DISALLOWED FILE TYPES in $repo:"
echo "$disallowed"
FAIL=1
fi
rm -rf "$tmp"
done
exit $FAIL