ci: restore Win7 TLS prebuilts from main artifacts

This commit is contained in:
luo jiyin
2026-10-18 00:42:17 +08:00
committed by GitHub
parent b3a6159b40
commit 3c5c6a2537
6 changed files with 223 additions and 28 deletions
+6
View File
@@ -163,6 +163,12 @@ successful builds would otherwise keep restoring the unfinished snapshot.
The first successful main run must populate the new namespace before fork PRs can
reuse it. Target caching is not a per-commit snapshot of workspace artifacts.
The Win7 job looks up AWS-LC and OpenSSL artifacts from main runs.
Each artifact name includes the fixture hash and the pinned nightly toolchain.
If an artifact is absent or expires, the job builds that dependency.
Main uploads each new artifact for 30 days. PRs do not upload copies.
Run `node .github/scripts/find-win7-prebuilt-artifact.mjs --help` for lookup usage.
Clippy, nextest and native Agent nextest builds emit Cargo HTML timing reports.
Their `DBX-*-cargo-timings` artifacts are retained for three days, including after
failures when a report exists, but uploads do not delay cancelled runs. Inspect
+18 -2
View File
@@ -361,11 +361,27 @@ test("Windows compatibility jobs cache Rust compilation without wrapping C or C+
assert.doesNotMatch(win7, /^\s+(?:CC|CXX):/m);
});
test("Win7 TLS cache keys ignore the workspace lockfile", () => {
test("Win7 TLS artifact names ignore the workspace lockfile", () => {
const win7 = job("windows-win7-bundle");
assert.ok(win7.includes("hashFiles('.github/fixtures/win7-aws-lc-cache/Cargo.toml', '.github/fixtures/win7-aws-lc-cache/Cargo.lock')"));
assert.ok(win7.includes("hashFiles('.github/fixtures/win7-openssl-cache/Cargo.toml', '.github/fixtures/win7-openssl-cache/Cargo.lock')"));
assert.doesNotMatch(win7, /key: win7-(?:aws-lc|openssl).*hashFiles\('Cargo\.lock'/);
assert.doesNotMatch(win7, /WIN7_PREBUILT_ARTIFACT_NAME: win7-(?:aws-lc|openssl).*hashFiles\('Cargo\.lock'/);
});
test("Win7 TLS artifacts come from main and retain a build fallback", () => {
const win7 = job("windows-win7-bundle");
assert.ok(win7.includes("actions: read"));
assert.doesNotMatch(win7, /uses: actions\/cache(?:\/restore|\/save)?@v4/);
for (const [name, id] of [["AWS-LC", "aws-lc-artifact"], ["OpenSSL", "openssl-artifact"]]) {
assert.ok(win7.includes(`if: steps.${id}.outputs.run_id != ''`));
assert.ok(win7.includes(`if: steps.${id}.outputs.run_id == ''`));
assert.ok(win7.includes(`if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.${id}.outputs.run_id == ''`));
assert.ok(win7.includes(`name: \${{ steps.${id}.outputs.name }}`));
assert.ok(win7.indexOf(`name: Find prebuilt Win7 ${name} artifact`) < win7.indexOf(`name: Download prebuilt Win7 ${name} artifact`));
assert.ok(win7.indexOf(`name: Download prebuilt Win7 ${name} artifact`) < win7.indexOf(`name: Build prebuilt Win7 ${name}`));
assert.ok(win7.indexOf(`name: Build prebuilt Win7 ${name}`) < win7.indexOf(`name: Upload prebuilt Win7 ${name} on main`));
assert.ok(win7.indexOf(`name: Configure prebuilt Win7 ${name}`) < win7.indexOf(`name: Upload prebuilt Win7 ${name} on main`));
}
});
test("path filtering and the planner use the exact test merge first parent", () => {
@@ -0,0 +1,64 @@
import { appendFileSync } from "node:fs";
import { pathToFileURL } from "node:url";
export function selectMainArtifact(artifacts, name, repositoryId) {
return artifacts
.filter((artifact) =>
artifact.name === name &&
!artifact.expired &&
artifact.workflow_run?.head_branch === "main" &&
artifact.workflow_run?.repository_id === repositoryId &&
artifact.workflow_run?.head_repository_id === repositoryId
)
.sort((left, right) => Date.parse(right.created_at) - Date.parse(left.created_at))[0];
}
export async function findMainArtifact({ name, repository, repositoryId, token, request = fetch }) {
const url = new URL(`https://api.github.com/repos/${repository}/actions/artifacts`);
url.searchParams.set("name", name);
url.searchParams.set("per_page", "100");
const response = await request(url, {
headers: {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2022-11-28",
},
});
if (!response.ok) throw new Error(`GitHub artifact lookup returned HTTP ${response.status}`);
const result = await response.json();
return selectMainArtifact(result.artifacts ?? [], name, repositoryId);
}
async function main() {
if (process.argv.includes("-h") || process.argv.includes("--help")) {
console.log("Usage: WIN7_PREBUILT_ARTIFACT_NAME=NAME node find-win7-prebuilt-artifact.mjs");
return;
}
const name = process.env.WIN7_PREBUILT_ARTIFACT_NAME;
const repository = process.env.GITHUB_REPOSITORY;
const repositoryId = Number(process.env.GITHUB_REPOSITORY_ID);
const token = process.env.GITHUB_TOKEN;
const output = process.env.GITHUB_OUTPUT;
if (!name || !repository || !Number.isSafeInteger(repositoryId) || !token || !output) {
throw new Error("Win7 artifact lookup requires a name, repository, repository ID, token, and output path.");
}
let runId = "";
try {
const artifact = await findMainArtifact({ name, repository, repositoryId, token });
runId = artifact ? String(artifact.workflow_run.id) : "";
} catch (error) {
console.warn(`Win7 artifact lookup failed. The job will build locally. ${error.message}`);
}
appendFileSync(output, `name=${name}\nrun_id=${runId}\n`);
console.log(runId ? `Found main artifact from run ${runId}.` : "No main artifact found. The job will build locally.");
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
main().catch((error) => {
console.error(error.message);
process.exitCode = 1;
});
}
@@ -0,0 +1,67 @@
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import test from "node:test";
import { fileURLToPath } from "node:url";
import { findMainArtifact, selectMainArtifact } from "./find-win7-prebuilt-artifact.mjs";
const repositoryId = 1224172037;
const name = "win7-aws-lc-test";
const artifact = (id, branch, headRepositoryId = repositoryId) => ({
name,
expired: false,
created_at: `2026-10-17T00:00:0${id}Z`,
workflow_run: {
id,
head_branch: branch,
repository_id: repositoryId,
head_repository_id: headRepositoryId,
},
});
test("artifact lookup ignores PR and fork artifacts", () => {
const selected = selectMainArtifact([
artifact(1, "main"),
artifact(2, "feature"),
artifact(3, "main", 999),
{ ...artifact(4, "main"), expired: true },
artifact(5, "main"),
], name, repositoryId);
assert.equal(selected.workflow_run.id, 5);
});
test("artifact lookup requests the exact name", async () => {
const selected = await findMainArtifact({
name,
repository: "t8y2/dbx",
repositoryId,
token: "synthetic",
request: async (url, options) => {
assert.equal(url.searchParams.get("name"), name);
assert.equal(options.headers.Authorization, "Bearer synthetic");
return { ok: true, json: async () => ({ artifacts: [artifact(6, "main")] }) };
},
});
assert.equal(selected.workflow_run.id, 6);
});
test("artifact lookup reports API errors", async () => {
await assert.rejects(
findMainArtifact({
name,
repository: "t8y2/dbx",
repositoryId,
token: "synthetic",
request: async () => ({ ok: false, status: 503 }),
}),
/HTTP 503/,
);
});
test("artifact lookup has a help command", () => {
const script = fileURLToPath(new URL("./find-win7-prebuilt-artifact.mjs", import.meta.url));
const result = spawnSync(process.execPath, [script], { encoding: "utf8", env: {} });
assert.equal(result.status, 1);
const help = spawnSync(process.execPath, [script, "--help"], { encoding: "utf8", env: {} });
assert.equal(help.status, 0);
assert.match(help.stdout, /Usage:/);
});
+67 -25
View File
@@ -361,6 +361,9 @@ jobs:
if: needs.changes.outputs.windows_win7_bundle == 'true'
runs-on: windows-2022
timeout-minutes: 120
permissions:
actions: read
contents: read
env:
CARGO_INCREMENTAL: "0"
CARGO_PROFILE_RELEASE_LTO: "off"
@@ -373,7 +376,7 @@ jobs:
SCCACHE_GHA_VERSION: win7-webview2-1.0.902.49-v1
SCCACHE_IDLE_TIMEOUT: "0"
# Single source for the job's nightly pin: the toolchain step and the
# prebuilt AWS-LC cache key must move together.
# prebuilt AWS-LC artifact name must move together.
WIN7_NIGHTLY_TOOLCHAIN: nightly-2026-07-22
steps:
- uses: actions/checkout@v7
@@ -423,16 +426,26 @@ jobs:
echo "AWS_SECRET_ACCESS_KEY=${CACHE_SECRET_ACCESS_KEY}"
} >> "$GITHUB_ENV"
- name: Restore prebuilt Win7 AWS-LC
id: aws-lc-cache
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/win7-aws-lc-install
# The fixture manifest and lockfile define the prebuilt AWS-LC artifact.
key: win7-aws-lc-v3-${{ runner.os }}-${{ env.WIN7_NIGHTLY_TOOLCHAIN }}-${{ hashFiles('.github/fixtures/win7-aws-lc-cache/Cargo.toml', '.github/fixtures/win7-aws-lc-cache/Cargo.lock') }}
- name: Find prebuilt Win7 AWS-LC artifact
id: aws-lc-artifact
shell: pwsh
env:
GITHUB_TOKEN: ${{ github.token }}
WIN7_PREBUILT_ARTIFACT_NAME: win7-aws-lc-v3-${{ runner.os }}-${{ env.WIN7_NIGHTLY_TOOLCHAIN }}-${{ hashFiles('.github/fixtures/win7-aws-lc-cache/Cargo.toml', '.github/fixtures/win7-aws-lc-cache/Cargo.lock') }}
run: node .github/scripts/find-win7-prebuilt-artifact.mjs
- name: Build Win7 AWS-LC cache
if: steps.aws-lc-cache.outputs.cache-hit != 'true'
- name: Download prebuilt Win7 AWS-LC artifact
if: steps.aws-lc-artifact.outputs.run_id != ''
uses: actions/download-artifact@v4
with:
name: ${{ steps.aws-lc-artifact.outputs.name }}
path: ${{ runner.temp }}/win7-aws-lc-install
run-id: ${{ steps.aws-lc-artifact.outputs.run_id }}
repository: ${{ github.repository }}
github-token: ${{ github.token }}
- name: Build prebuilt Win7 AWS-LC
if: steps.aws-lc-artifact.outputs.run_id == ''
shell: pwsh
run: |
$timer = [System.Diagnostics.Stopwatch]::StartNew()
@@ -494,7 +507,7 @@ jobs:
}
$bindingLines | Set-Content -LiteralPath $bindingOutput -Encoding utf8NoBOM
$timer.Stop()
"AWS-LC cache build: $([math]::Round($timer.Elapsed.TotalSeconds, 1)) seconds" >> $env:GITHUB_STEP_SUMMARY
"AWS-LC prebuilt build: $([math]::Round($timer.Elapsed.TotalSeconds, 1)) seconds" >> $env:GITHUB_STEP_SUMMARY
env:
CARGO_TARGET_DIR: ${{ runner.temp }}/win7-aws-lc-build
@@ -510,24 +523,44 @@ jobs:
)
foreach ($relativePath in $requiredFiles) {
if (!(Test-Path (Join-Path $installRoot $relativePath))) {
Write-Error "The AWS-LC cache does not contain $relativePath."
Write-Error "The AWS-LC artifact does not contain $relativePath."
exit 1
}
}
"AWS_LC_SYS_SYSTEM_DIR=$installRoot" >> $env:GITHUB_ENV
"AWS_LC_SYS_USE_SYSTEM=1" >> $env:GITHUB_ENV
"AWS_LC_SYS_STATIC=1" >> $env:GITHUB_ENV
"AWS-LC cache hit: ${{ steps.aws-lc-cache.outputs.cache-hit }}" >> $env:GITHUB_STEP_SUMMARY
"AWS-LC artifact hit: ${{ steps.aws-lc-artifact.outputs.run_id != '' }}" >> $env:GITHUB_STEP_SUMMARY
- name: Restore prebuilt Win7 OpenSSL
id: openssl-cache
uses: actions/cache@v4
- name: Upload prebuilt Win7 AWS-LC on main
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.aws-lc-artifact.outputs.run_id == ''
uses: actions/upload-artifact@v6
with:
path: ${{ runner.temp }}/win7-openssl-install
key: win7-openssl-v1-${{ runner.os }}-${{ env.WIN7_NIGHTLY_TOOLCHAIN }}-${{ hashFiles('.github/fixtures/win7-openssl-cache/Cargo.toml', '.github/fixtures/win7-openssl-cache/Cargo.lock') }}
name: ${{ steps.aws-lc-artifact.outputs.name }}
path: ${{ runner.temp }}/win7-aws-lc-install/
if-no-files-found: error
retention-days: 30
- name: Build Win7 OpenSSL cache
if: steps.openssl-cache.outputs.cache-hit != 'true'
- name: Find prebuilt Win7 OpenSSL artifact
id: openssl-artifact
shell: pwsh
env:
GITHUB_TOKEN: ${{ github.token }}
WIN7_PREBUILT_ARTIFACT_NAME: win7-openssl-v1-${{ runner.os }}-${{ env.WIN7_NIGHTLY_TOOLCHAIN }}-${{ hashFiles('.github/fixtures/win7-openssl-cache/Cargo.toml', '.github/fixtures/win7-openssl-cache/Cargo.lock') }}
run: node .github/scripts/find-win7-prebuilt-artifact.mjs
- name: Download prebuilt Win7 OpenSSL artifact
if: steps.openssl-artifact.outputs.run_id != ''
uses: actions/download-artifact@v4
with:
name: ${{ steps.openssl-artifact.outputs.name }}
path: ${{ runner.temp }}/win7-openssl-install
run-id: ${{ steps.openssl-artifact.outputs.run_id }}
repository: ${{ github.repository }}
github-token: ${{ github.token }}
- name: Build prebuilt Win7 OpenSSL
if: steps.openssl-artifact.outputs.run_id == ''
shell: pwsh
run: |
$timer = [System.Diagnostics.Stopwatch]::StartNew()
@@ -550,7 +583,7 @@ jobs:
New-Item -ItemType Directory -Path $installRoot -Force | Out-Null
Copy-Item -Path (Join-Path $install.FullName "*") -Destination $installRoot -Recurse -Force
$timer.Stop()
"OpenSSL cache build: $([math]::Round($timer.Elapsed.TotalSeconds, 1)) seconds" >> $env:GITHUB_STEP_SUMMARY
"OpenSSL prebuilt build: $([math]::Round($timer.Elapsed.TotalSeconds, 1)) seconds" >> $env:GITHUB_STEP_SUMMARY
env:
CARGO_TARGET_DIR: ${{ runner.temp }}/win7-openssl-build
@@ -559,21 +592,30 @@ jobs:
run: |
$installRoot = Join-Path $env:RUNNER_TEMP "win7-openssl-install"
if (!(Test-Path (Join-Path $installRoot "include/openssl/ssl.h"))) {
Write-Error "The OpenSSL cache does not contain ssl.h."
Write-Error "The OpenSSL artifact does not contain ssl.h."
exit 1
}
if (!(Get-ChildItem (Join-Path $installRoot "lib") -Filter "*ssl*.lib")) {
Write-Error "The OpenSSL cache does not contain an SSL library."
Write-Error "The OpenSSL artifact does not contain an SSL library."
exit 1
}
if (!(Get-ChildItem (Join-Path $installRoot "lib") -Filter "*crypto*.lib")) {
Write-Error "The OpenSSL cache does not contain a crypto library."
Write-Error "The OpenSSL artifact does not contain a crypto library."
exit 1
}
"OPENSSL_DIR=$installRoot" >> $env:GITHUB_ENV
"OPENSSL_NO_VENDOR=1" >> $env:GITHUB_ENV
"OPENSSL_STATIC=1" >> $env:GITHUB_ENV
"OpenSSL cache hit: ${{ steps.openssl-cache.outputs.cache-hit }}" >> $env:GITHUB_STEP_SUMMARY
"OpenSSL artifact hit: ${{ steps.openssl-artifact.outputs.run_id != '' }}" >> $env:GITHUB_STEP_SUMMARY
- name: Upload prebuilt Win7 OpenSSL on main
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && steps.openssl-artifact.outputs.run_id == ''
uses: actions/upload-artifact@v6
with:
name: ${{ steps.openssl-artifact.outputs.name }}
path: ${{ runner.temp }}/win7-openssl-install/
if-no-files-found: error
retention-days: 30
- name: Prepare Win7-compatible WebView2 loader
shell: pwsh
+1 -1
View File
@@ -203,7 +203,7 @@
fetcherVersion = 4;
# Update with the hash reported by a failed fixed-output build:
# nix build .#dbx-pnpm-deps 2>&1 | grep 'got:'
hash = "sha256-AUHM0u41ObqzcAvJ/Kx6uLc/SAehBFjTYEJW0IKEPAM=";
hash = "sha256-3mlTqUtIlGuxgWnLHuvdem2VtjjEoCYkCCkqnMUJFgU=";
};
# ── Step 2: vendor Cargo dependencies ───────────────────────────── #