Skip to content

Commit 62c8a3f

Browse files
committed
fix: preserve target-triple build artifacts
1 parent 3cd715c commit 62c8a3f

7 files changed

Lines changed: 469 additions & 291 deletions

File tree

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: target-triple
2+
3+
on: [push, pull_request]
4+
5+
permissions: {}
6+
7+
jobs:
8+
save:
9+
if: github.repository == 'Swatinem/rust-cache'
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
os: [ubuntu-latest, macos-latest, windows-latest]
14+
15+
name: Save target-triple cache on ${{ matrix.os }}
16+
runs-on: ${{ matrix.os }}
17+
18+
steps:
19+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
20+
with:
21+
persist-credentials: false
22+
23+
- run: rustup toolchain install stable --profile minimal --no-self-update
24+
25+
- name: Set host target
26+
shell: bash
27+
run: |
28+
echo "RUST_TARGET=$(rustc -vV | sed -n 's/^host: //p')" >> "$GITHUB_ENV"
29+
30+
- uses: ./
31+
with:
32+
workspaces: tests
33+
shared-key: target-triple-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
34+
add-job-id-key: "false"
35+
add-rust-environment-hash-key: "false"
36+
37+
- run: cargo check --target "$RUST_TARGET"
38+
working-directory: tests
39+
shell: bash
40+
41+
restore:
42+
if: github.repository == 'Swatinem/rust-cache'
43+
strategy:
44+
fail-fast: false
45+
matrix:
46+
os: [ubuntu-latest, macos-latest, windows-latest]
47+
48+
name: Restore target-triple cache on ${{ matrix.os }}
49+
needs: save
50+
runs-on: ${{ matrix.os }}
51+
52+
steps:
53+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
54+
with:
55+
persist-credentials: false
56+
57+
- run: rustup toolchain install stable --profile minimal --no-self-update
58+
59+
- name: Set host target
60+
shell: bash
61+
run: |
62+
echo "RUST_TARGET=$(rustc -vV | sed -n 's/^host: //p')" >> "$GITHUB_ENV"
63+
64+
- id: cache
65+
uses: ./
66+
with:
67+
workspaces: tests
68+
shared-key: target-triple-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
69+
add-job-id-key: "false"
70+
add-rust-environment-hash-key: "false"
71+
save-if: "false"
72+
73+
- name: Verify target-triple artifacts
74+
env:
75+
CACHE_HIT: ${{ steps.cache.outputs.cache-hit }}
76+
shell: bash
77+
run: |
78+
if [[ "$CACHE_HIT" != "true" ]]; then
79+
echo "The target-triple cache was not restored exactly." >&2
80+
exit 1
81+
fi
82+
if ! compgen -G "tests/target/$RUST_TARGET/debug/deps/rust_cache-*" > /dev/null; then
83+
echo "The target-triple artifacts were not restored." >&2
84+
exit 1
85+
fi
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { v as commonjsGlobal, x as requireTunnel, m as getDefaultExportFromCjs, y as getAugmentedNamespace } from './cleanup-ChNUL7jL.js';
1+
import { v as commonjsGlobal, x as requireTunnel, m as getDefaultExportFromCjs, y as getAugmentedNamespace } from './cleanup-DrKoHb3w.js';
22
import os__default from 'os';
33
import crypto__default from 'crypto';
44
import fs__default from 'fs';
Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { f as debug, m as getDefaultExportFromCjs, n as mkdirP, l as exec, w as which, o as warning, i as info, H as HttpCodes, p as HttpClientError, q as HttpClient, t as isDebug, u as setSecret, B as BearerCredentialHandler, e as error } from './cleanup-ChNUL7jL.js';
1+
import { f as debug, m as getDefaultExportFromCjs, n as mkdirP, l as exec, w as which, o as warning, i as info, H as HttpCodes, p as HttpClientError, q as HttpClient, t as isDebug, u as setSecret, B as BearerCredentialHandler, e as error } from './cleanup-DrKoHb3w.js';
22
import * as path from 'path';
33
import * as fs from 'fs';
44
import { writeFileSync, existsSync } from 'fs';
@@ -44263,7 +44263,7 @@ function getCacheServiceURL() {
4426344263
}
4426444264
}
4426544265

44266-
var version = "6.0.1";
44266+
var version = "6.1.0";
4426744267
var require$$0 = {
4426844268
version: version};
4426944269

@@ -48513,6 +48513,35 @@ class ReserveCacheError extends Error {
4851348513
Object.setPrototypeOf(this, ReserveCacheError.prototype);
4851448514
}
4851548515
}
48516+
/**
48517+
* Stable prefix the receiver writes into the cache reservation response when
48518+
* the issuer downgraded the cache token to read-only (for example, because
48519+
* the run was triggered by an untrusted event). saveCacheV1 / saveCacheV2
48520+
* dispatch on this prefix to re-classify the failure as a
48521+
* CacheWriteDeniedError so consumers (and the outer catch arm) can
48522+
* distinguish a policy denial from other reservation failures.
48523+
*/
48524+
const CACHE_WRITE_DENIED_PREFIX = 'cache write denied:';
48525+
/**
48526+
* Raised when the cache backend refuses to reserve a writable cache entry
48527+
* because the JWT issued for this run was scoped read-only (for example, the
48528+
* run was triggered by an event the repository administrator classified as
48529+
* untrusted). The receiver-supplied detail message always begins with
48530+
* `cache write denied:` (the full error message includes additional context
48531+
* like the cache key).
48532+
*
48533+
* Extends ReserveCacheError for source-compatibility: existing
48534+
* `instanceof ReserveCacheError` checks and `typedError.name ===
48535+
* ReserveCacheError.name` paths keep working, while consumers that want to
48536+
* distinguish the policy case can match on this subclass.
48537+
*/
48538+
class CacheWriteDeniedError extends ReserveCacheError {
48539+
constructor(message) {
48540+
super(message);
48541+
this.name = 'CacheWriteDeniedError';
48542+
Object.setPrototypeOf(this, CacheWriteDeniedError.prototype);
48543+
}
48544+
}
4851648545
class FinalizeCacheError extends Error {
4851748546
constructor(message) {
4851848547
super(message);
@@ -48785,7 +48814,7 @@ function saveCache(paths_1, key_1, options_1) {
4878548814
*/
4878648815
function saveCacheV1(paths_1, key_1, options_1) {
4878748816
return __awaiter(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) {
48788-
var _a, _b, _c, _d, _e;
48817+
var _a, _b, _c, _d, _e, _f;
4878948818
const compressionMethod = yield getCompressionMethod();
4879048819
let cacheId = -1;
4879148820
const cachePaths = yield resolvePaths(paths);
@@ -48822,7 +48851,17 @@ function saveCacheV1(paths_1, key_1, options_1) {
4882248851
throw new Error((_d = (_c = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _c === void 0 ? void 0 : _c.message) !== null && _d !== void 0 ? _d : `Cache size of ~${Math.round(archiveFileSize / (1024 * 1024))} MB (${archiveFileSize} B) is over the data cap limit, not saving cache.`);
4882348852
}
4882448853
else {
48825-
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${(_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message}`);
48854+
// Inspect the receiver's error message before deciding which error to
48855+
// throw. A message starting with the stable `cache write denied:`
48856+
// prefix indicates the issuer downgraded the token to read-only
48857+
// (policy denial), not a contention case, so we surface it as a
48858+
// CacheWriteDeniedError which the outer catch arm logs at warning
48859+
// level.
48860+
const detailMessage = (_e = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _e === void 0 ? void 0 : _e.message;
48861+
if (detailMessage === null || detailMessage === void 0 ? void 0 : detailMessage.startsWith(CACHE_WRITE_DENIED_PREFIX)) {
48862+
throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${detailMessage}`);
48863+
}
48864+
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache. More details: ${(_f = reserveCacheResponse === null || reserveCacheResponse === void 0 ? void 0 : reserveCacheResponse.error) === null || _f === void 0 ? void 0 : _f.message}`);
4882648865
}
4882748866
debug(`Saving Cache (ID: ${cacheId})`);
4882848867
yield saveCache$1(cacheId, archivePath, '', options);
@@ -48832,6 +48871,12 @@ function saveCacheV1(paths_1, key_1, options_1) {
4883248871
if (typedError.name === ValidationError.name) {
4883348872
throw error$1;
4883448873
}
48874+
else if (typedError.name === CacheWriteDeniedError.name) {
48875+
// Cache write was denied by policy (read-only token). Surface to the
48876+
// customer at warning level so it is visible in the workflow log
48877+
// without failing the run.
48878+
warning(`Failed to save: ${typedError.message}`);
48879+
}
4883548880
else if (typedError.name === ReserveCacheError.name) {
4883648881
info(`Failed to save: ${typedError.message}`);
4883748882
}
@@ -48870,6 +48915,7 @@ function saveCacheV1(paths_1, key_1, options_1) {
4887048915
*/
4887148916
function saveCacheV2(paths_1, key_1, options_1) {
4887248917
return __awaiter(this, arguments, void 0, function* (paths, key, options, enableCrossOsArchive = false) {
48918+
var _a;
4887348919
// Override UploadOptions to force the use of Azure
4887448920
// ...options goes first because we want to override the default values
4887548921
// set in UploadOptions with these specific figures
@@ -48905,7 +48951,11 @@ function saveCacheV2(paths_1, key_1, options_1) {
4890548951
try {
4890648952
const response = yield twirpClient.CreateCacheEntry(request);
4890748953
if (!response.ok) {
48908-
if (response.message) {
48954+
// Skip the redundant inner warning when the receiver signalled a
48955+
// policy denial: the outer catch arm below will log a single
48956+
// customer-facing warning.
48957+
if (response.message &&
48958+
!response.message.startsWith(CACHE_WRITE_DENIED_PREFIX)) {
4890948959
warning(`Cache reservation failed: ${response.message}`);
4891048960
}
4891148961
throw new Error(response.message || 'Response was not ok');
@@ -48914,6 +48964,10 @@ function saveCacheV2(paths_1, key_1, options_1) {
4891448964
}
4891548965
catch (error) {
4891648966
debug(`Failed to reserve cache: ${error}`);
48967+
const errorMessage = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : '';
48968+
if (errorMessage.startsWith(CACHE_WRITE_DENIED_PREFIX)) {
48969+
throw new CacheWriteDeniedError(`Unable to reserve cache with key ${key}. More details: ${errorMessage}`);
48970+
}
4891748971
throw new ReserveCacheError(`Unable to reserve cache with key ${key}, another job may be creating this cache.`);
4891848972
}
4891948973
debug(`Attempting to upload cache located at: ${archivePath}`);
@@ -48938,6 +48992,12 @@ function saveCacheV2(paths_1, key_1, options_1) {
4893848992
if (typedError.name === ValidationError.name) {
4893948993
throw error$1;
4894048994
}
48995+
else if (typedError.name === CacheWriteDeniedError.name) {
48996+
// Cache write was denied by policy (read-only token). Surface to the
48997+
// customer at warning level so it is visible in the workflow log
48998+
// without failing the run.
48999+
warning(`Failed to save: ${typedError.message}`);
49000+
}
4894149001
else if (typedError.name === ReserveCacheError.name) {
4894249002
info(`Failed to save: ${typedError.message}`);
4894349003
}
@@ -48969,4 +49029,4 @@ function saveCacheV2(paths_1, key_1, options_1) {
4896949029
});
4897049030
}
4897149031

48972-
export { FinalizeCacheError, ReserveCacheError, ValidationError, isFeatureAvailable, restoreCache, saveCache };
49032+
export { CACHE_WRITE_DENIED_PREFIX, CacheWriteDeniedError, FinalizeCacheError, ReserveCacheError, ValidationError, isFeatureAvailable, restoreCache, saveCache };

0 commit comments

Comments
 (0)