Raise slow CI job time limits and prune closed pull request caches (#1994)

This commit is contained in:
Chris Tate
2026-10-24 17:33:56 -05:00
committed by GitHub
5 changed files with 68 additions and 17 deletions
+5 -2
View File
@@ -539,6 +539,8 @@ jobs:
if: ${{ needs.validation_scope.outputs.full == 'true' && needs.lanes.outputs.linux == 'true' }}
name: test (tsgo and tsc-ts give the same IR)
runs-on: ubuntu-24.04
# The two corpus compiles run back to back and take close to 30 minutes on a
# slow hosted runner, so a 30-minute limit cancels otherwise healthy runs.
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
@@ -633,8 +635,9 @@ jobs:
# Shard 1 additionally runs package/install and link-parity contracts
# before its LLVM differential slice. The slice itself can take ~10
# minutes on a cold hosted runner, so 20 minutes cancels an otherwise
# healthy job before the differential completes.
timeout-minutes: 35
# healthy job before the differential completes. Slow runners need more
# headroom than that, so the limit is 50 minutes.
timeout-minutes: 50
strategy:
fail-fast: false
matrix:
+41
View File
@@ -0,0 +1,41 @@
name: Prune caches
# Pull request caches are scoped to that pull request, so once it is closed no
# run can use them again. Deleting them keeps the repository under its cache
# size limit, so caches that main and open pull requests use are not evicted.
on:
pull_request:
types: [closed]
schedule:
- cron: "17 6 * * *"
workflow_dispatch:
permissions:
actions: write
pull-requests: read
jobs:
prune:
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Delete caches of closed pull requests
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
# Read both lists in full before deleting anything: deleting while the cache
# listing pages shifts later pages, and a failed request must stop the job
# instead of leaving open pull requests out of the list.
open=$(gh api --paginate "repos/$REPO/pulls?state=open&per_page=100" --jq '.[].number')
caches=$(gh api --paginate "repos/$REPO/actions/caches?per_page=100" \
--jq '.actions_caches[] | select(.ref | startswith("refs/pull/")) | "\(.id) \(.ref)"')
while read -r id ref; do
[ -n "$id" ] || continue
number=$(echo "$ref" | cut -d/ -f3)
if ! grep -qx "$number" <<<"$open"; then
gh api --method DELETE "repos/$REPO/actions/caches/$id" >/dev/null
echo "deleted cache $id ($ref)"
fi
done <<<"$caches"
@@ -21,5 +21,5 @@ module.exports = function run() {
console.log(e instanceof TypeError, e.message.length, e.message.slice(0, 30), e.message.slice(-40));
}
child.on("close", (code) => console.log("close", code, child.killedBy));
child.kill("SIGTERM");
child.stdout.once("data", () => child.kill("SIGTERM"));
};
@@ -5,17 +5,24 @@
// and writes a getter-only property with a long name.
const patched = require("./patcher.cjs");
const definer = require("./definer.cjs");
const child = patched();
console.log(child.label);
child.label = "x";
console.log(child.stored, child.same);
try {
child.same = 1;
} catch (e) {
console.log(e instanceof TypeError, e.message);
if (process.argv.at(2) === "child") {
// The child reports that it started, then waits for the parent's SIGTERM.
// It exits after 30 seconds without one.
process.stdout.write("ready");
setTimeout(() => {}, 30000);
} else {
const child = patched();
console.log(child.label);
child.label = "x";
console.log(child.stored, child.same);
try {
child.same = 1;
} catch (e) {
console.log(e instanceof TypeError, e.message);
}
child.on("close", (code) => {
console.log("close", code, child.killedBy);
});
child.stdout.once("data", () => child.kill("SIGTERM"));
child.on("close", () => definer());
}
child.on("close", (code) => {
console.log("close", code, child.killedBy);
});
child.kill("SIGTERM");
child.on("exit", () => definer());
@@ -1,5 +1,5 @@
"use strict";
const { spawn } = require("child_process");
module.exports = function start() {
return spawn(process.execPath, ["-e", "process.stdout.write('ok')"]);
return spawn(process.execPath, [process.argv[1], "child"]);
};