@plainconceptsplatform/workflows 1.21.0 → 1.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3731,6 +3731,12 @@ rc 'side-checks\.sh' "${HERE}/../merge-agent-pr/action.yml" 'merge-agent-pr must
|
|
|
3731
3731
|
rc 'land-pull-request/side-checks\.sh' "${HERE}/../merge-train/merge-train.sh" 'the merge train must hold a pull request whose side workflow is red'
|
|
3732
3732
|
rc 'test-timings\.mjs' "$CI_DOTNET" 'the .NET template must summarise the test timings'
|
|
3733
3733
|
[ "$(grep -c -- '--logger trx' "$CI_DOTNET")" -ge 5 ] || { RC_OK=0; echo "FAIL: required checks: every .NET test step must write a trx report" >&2; }
|
|
3734
|
+
# The template sync installs copier on a runner whose Python cannot make a venv: the pinned uv it
|
|
3735
|
+
# falls back to must stay checked against its SHA-256, or the sync never runs (it never had).
|
|
3736
|
+
SYNC_YML="${HERE}/../../templates/platform-template/.github/workflows/platform-template-sync.yml"
|
|
3737
|
+
rc '^ UV_SHA256: [0-9a-f]{64}$' "$SYNC_YML" 'the template sync must pin uv by SHA-256'
|
|
3738
|
+
rc 'sha256sum --check --strict' "$SYNC_YML" 'the template sync must check the uv download'
|
|
3739
|
+
rc "python3 -c 'import ensurepip'" "$SYNC_YML" 'the template sync must not try a venv where ensurepip is missing'
|
|
3734
3740
|
if [ "$RC_OK" -eq 1 ]; then PASS=$((PASS + 1)); else FAIL=$((FAIL + 1)); fi
|
|
3735
3741
|
|
|
3736
3742
|
echo "── App error privacy ─────────────────────────────────────────────────────"
|
|
@@ -25,6 +25,10 @@ concurrency:
|
|
|
25
25
|
env:
|
|
26
26
|
# copier 9.19.1 needs Python 3.10 or newer on the runner.
|
|
27
27
|
COPIER_VERSION: "9.19.1"
|
|
28
|
+
# The pinned uv the copier step downloads when the runner has no uvx, no pipx and no ensurepip
|
|
29
|
+
# (the self-hosted runner image ships Python without python3-venv, so a venv cannot be made).
|
|
30
|
+
UV_VERSION: "0.13.5"
|
|
31
|
+
UV_SHA256: f68d291c75783122dad58ab77def0e13f3233f358731db5d6d7e8715603b928f
|
|
28
32
|
NODE_VERSION: "22"
|
|
29
33
|
SYNC_BRANCH: platform/template-sync
|
|
30
34
|
|
|
@@ -79,7 +83,8 @@ jobs:
|
|
|
79
83
|
private-key: ${{ secrets.BOT_PRIVATE_KEY }}
|
|
80
84
|
owner: ${{ github.repository_owner }}
|
|
81
85
|
|
|
82
|
-
# uvx where uv is installed, then pipx, then a virtual environment from the runner's Python
|
|
86
|
+
# uvx where uv is installed, then pipx, then a virtual environment from the runner's Python, and
|
|
87
|
+
# where that Python cannot make one, a pinned uv checked against its SHA-256.
|
|
83
88
|
- name: Install copier
|
|
84
89
|
if: steps.decide.outputs.run == 'true' && startsWith(steps.contract.outputs.update, 'copier ')
|
|
85
90
|
run: |
|
|
@@ -90,10 +95,16 @@ jobs:
|
|
|
90
95
|
run="uvx --from copier==$COPIER_VERSION copier"
|
|
91
96
|
elif command -v pipx >/dev/null 2>&1; then
|
|
92
97
|
run="pipx run --spec copier==$COPIER_VERSION copier"
|
|
93
|
-
|
|
98
|
+
elif python3 -c 'import ensurepip' >/dev/null 2>&1; then
|
|
94
99
|
python3 -m venv "$RUNNER_TEMP/copier-venv"
|
|
95
100
|
"$RUNNER_TEMP/copier-venv/bin/pip" install --quiet "copier==$COPIER_VERSION"
|
|
96
101
|
run="$RUNNER_TEMP/copier-venv/bin/copier"
|
|
102
|
+
else
|
|
103
|
+
tarball="$RUNNER_TEMP/uv.tar.gz"
|
|
104
|
+
curl -fsSL -o "$tarball" "https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/uv-x86_64-unknown-linux-gnu.tar.gz"
|
|
105
|
+
echo "${UV_SHA256} $tarball" | sha256sum --check --strict
|
|
106
|
+
tar -xzf "$tarball" -C "$RUNNER_TEMP"
|
|
107
|
+
run="$RUNNER_TEMP/uv-x86_64-unknown-linux-gnu/uvx --from copier==$COPIER_VERSION copier"
|
|
97
108
|
fi
|
|
98
109
|
cat > "$bin/copier" <<EOF
|
|
99
110
|
#!/usr/bin/env bash
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
// Reads VSTest .trx reports and says where a test run's time goes: by test class, since a class is
|
|
4
4
|
// what xUnit runs in parallel and where a fixture's setup is paid once.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// One literal pattern reads every attribute of a tag: Semgrep blocks a RegExp built from a variable.
|
|
7
|
+
const attr = (tag, name) => Object.fromEntries([...tag.matchAll(/([\w:]+)="([^"]*)"/g)].map(([, key, value]) => [key, value]))[name];
|
|
7
8
|
|
|
8
9
|
function seconds(duration) {
|
|
9
10
|
const [h, m, s] = (duration ?? '0:0:0').split(':');
|