diff --git a/CHANGELOG.md b/CHANGELOG.md
index b794be7c9..497c96e91 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic
Versioning](https://semver.org/spec/v2.0.0.html).
-
+## Unreleased
+
+### Added
+
+- Added support for the `v2` version of the
+ `google/wireit@setup-github-actions-caching` action, which provides improved
+ security. All users are advised to upgrade to
+ `google/wireit@setup-github-actions-caching/v2`.
## [0.14.5] - 2024-07-08
diff --git a/README.md b/README.md
index 0f23f20d7..6eea67cc9 100644
--- a/README.md
+++ b/README.md
@@ -360,7 +360,7 @@ clause to your workflow. It can appear anywhere before the first `npm run` or
`npm test` command:
```yaml
-- uses: google/wireit@setup-github-actions-caching/v1
+- uses: google/wireit@setup-github-actions-caching/v2
```
#### Example workflow
@@ -381,7 +381,7 @@ jobs:
cache: npm
# Set up GitHub Actions caching for Wireit.
- - uses: google/wireit@setup-github-actions-caching/v1
+ - uses: google/wireit@setup-github-actions-caching/v2
# Install npm dependencies.
- run: npm ci
@@ -857,7 +857,7 @@ The following environment variables affect the behavior of Wireit:
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WIREIT_FAILURES` | [How to handle script failures](#failures-and-errors).
Options:
- [`no-new`](#failures-and-errors) (default): Allow running scripts to finish, but don't start new ones.
- [`continue`](#continue): Allow running scripts to continue, and start new ones unless any of their dependencies failed.
- [`kill`](#kill): Immediately kill running scripts, and don't start new ones.
|
| `WIREIT_PARALLEL` | [Maximum number of scripts to run at one time](#parallelism).
Defaults to 2×logical CPU cores.
Must be a positive integer or `infinity`. |
-| `WIREIT_CACHE` | [Caching mode](#caching).
Defaults to `local` unless `CI` is `true`, in which case defaults to `none`.
Automatically set to `github` by the [`google/wireit@setup-github-actions-caching/v1`](#github-actions-caching) action.
Options:- [`local`](#local-caching): Cache to local disk.
- [`github`](#github-actions-caching): Cache to GitHub Actions.
- `none`: Disable caching.
|
+| `WIREIT_CACHE` | [Caching mode](#caching).
Defaults to `local` unless `CI` is `true`, in which case defaults to `none`.
Automatically set to `github` by the [`google/wireit@setup-github-actions-caching/v2`](#github-actions-caching) action.
Options:- [`local`](#local-caching): Cache to local disk.
- [`github`](#github-actions-caching): Cache to GitHub Actions.
- `none`: Disable caching.
|
| `CI` | Affects the default value of `WIREIT_CACHE`.
Automatically set to `true` by [GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables) and most other CI (continuous integration) services.
Must be exactly `true`. If unset or any other value, interpreted as `false`. |
| `WIREIT_MAX_OPEN_FILES` | Limits the number of file descriptors Wireit will have open concurrently. Prevents resource exhaustion when checking large numbers of cached files. Set to a lower number if you hit file descriptor limits. |
| `WIREIT_LOGGER` | How to present progress and results on the command line.
Options:
- `quiet` (default): writes a single dynamically updating line summarizing progress. Only passes along stdout and stderr from commands if there's a failure, or if the command is a service. The planned new default, please try it out.
- `simple` (default): A verbose logger that presents clear information about the work that Wireit is doing.
- `metrics`: Like `simple`, but also presents a summary table of results once a command is finished.
- `quiet-ci` (default when env.CI or !stdout.isTTY): like `quiet` but optimized for non-interactive environments, like GitHub Actions runners.
|
diff --git a/src/caching/github-actions-cache.ts b/src/caching/github-actions-cache.ts
index ab21f8090..7d1a51573 100644
--- a/src/caching/github-actions-cache.ts
+++ b/src/caching/github-actions-cache.ts
@@ -23,6 +23,7 @@ import type {Fingerprint} from '../fingerprint.js';
import type {Logger} from '../logging/logger.js';
import type {AbsoluteEntry} from '../util/glob.js';
import type {Result} from '../error.js';
+import type {InvalidUsage, UnknownErrorThrown} from '../event.js';
/**
* Caches script output to the GitHub Actions caching service.
@@ -48,9 +49,80 @@ export class GitHubActionsCache implements Cache {
this.#logger = logger;
}
- static create(
+ static async create(
logger: Logger,
- ): Result {
+ ): Promise<
+ Result<
+ GitHubActionsCache,
+ Omit | Omit
+ >
+ > {
+ const custodianPort = process.env['WIREIT_CACHE_GITHUB_CUSTODIAN_PORT'];
+ if (custodianPort === undefined) {
+ if (
+ process.env['ACTIONS_RUNTIME_TOKEN'] !== undefined ||
+ process.env['ACTIONS_CACHE_URL'] !== undefined
+ ) {
+ console.warn(
+ '⚠️ Please upgrade to google/wireit@setup-github-cache/v2. ' +
+ 'In the future, Wireit caching for this project will stop working.\n',
+ );
+ return GitHubActionsCache.#deprecatedCreate(logger);
+ }
+ return {
+ ok: false,
+ error: {
+ type: 'failure',
+ reason: 'invalid-usage',
+ message:
+ 'The WIREIT_CACHE_GITHUB_CUSTODIAN_PORT environment variable was ' +
+ 'not set, but is required when WIREIT_CACHE=github. Use the ' +
+ 'google/wireit@setup-github-cache/v2 action to automatically set ' +
+ 'this environment variable.',
+ },
+ };
+ }
+ const custodianUrl = `http://localhost:${custodianPort}`;
+ let result: {
+ caching: {
+ github: {
+ ACTIONS_CACHE_URL: string;
+ ACTIONS_RUNTIME_TOKEN: string;
+ };
+ };
+ };
+ try {
+ const response = await fetch(custodianUrl);
+ if (!response.ok) {
+ throw new Error(`HTTP status ${response.status}`);
+ }
+ result = (await response.json()) as typeof result;
+ } catch (error) {
+ return {
+ ok: false,
+ error: {
+ type: 'failure',
+ reason: 'unknown-error-thrown',
+ error: new Error(
+ `Error communicating with cache token mediator service: ` +
+ String(error),
+ ),
+ },
+ };
+ }
+ return {
+ ok: true,
+ value: new GitHubActionsCache(
+ logger,
+ result.caching.github.ACTIONS_CACHE_URL,
+ result.caching.github.ACTIONS_RUNTIME_TOKEN,
+ ),
+ };
+ }
+
+ static #deprecatedCreate(
+ logger: Logger,
+ ): Result> {
// The ACTIONS_CACHE_URL and ACTIONS_RUNTIME_TOKEN environment variables are
// automatically provided to GitHub Actions re-usable workflows. However,
// they are _not_ provided to regular "run" scripts. For this reason, we
@@ -63,6 +135,7 @@ export class GitHubActionsCache implements Cache {
return {
ok: false,
error: {
+ type: 'failure',
reason: 'invalid-usage',
message:
'The ACTIONS_CACHE_URL variable was not set, but is required when ' +
@@ -78,6 +151,7 @@ export class GitHubActionsCache implements Cache {
return {
ok: false,
error: {
+ type: 'failure',
reason: 'invalid-usage',
message: `The ACTIONS_CACHE_URL must end in a forward-slash, got ${JSON.stringify(
baseUrl,
@@ -92,6 +166,7 @@ export class GitHubActionsCache implements Cache {
return {
ok: false,
error: {
+ type: 'failure',
reason: 'invalid-usage',
message:
'The ACTIONS_RUNTIME_TOKEN variable was not set, but is required when ' +
diff --git a/src/cli.ts b/src/cli.ts
index 30defe6e0..12976cc82 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -30,28 +30,17 @@ const run = async (options: Options): Promise> => {
const {GitHubActionsCache} = await import(
'./caching/github-actions-cache.js'
);
- const cacheResult = GitHubActionsCache.create(logger);
+ const cacheResult = await GitHubActionsCache.create(logger);
if (!cacheResult.ok) {
- if (cacheResult.error.reason === 'invalid-usage') {
- return {
- ok: false,
- error: [
- {
- script: options.script,
- type: 'failure',
- reason: 'invalid-usage',
- message: cacheResult.error.message,
- },
- ],
- };
- } else {
- const never: never = cacheResult.error.reason;
- throw new Error(
- `Internal error: unexpected cache result error reason: ${String(
- never,
- )}`,
- );
- }
+ return {
+ ok: false,
+ error: [
+ {
+ script: options.script,
+ ...cacheResult.error,
+ },
+ ],
+ };
}
cache = cacheResult.value;
break;
diff --git a/src/test/cache-common.ts b/src/test/cache-common.ts
index 6f4bca0fe..ca7b67f0e 100644
--- a/src/test/cache-common.ts
+++ b/src/test/cache-common.ts
@@ -990,7 +990,7 @@ export const registerCommonCacheTests = (
assert.equal(res.code, 1);
checkScriptOutput(
res.stderr,
- `
+ `${cacheMode === 'github' ? '⚠️ Please upgrade to google/wireit@setup-github-cache/v2. In the future, Wireit caching for this project will stop working.\n' : ''}
❌ package.json:9:17 Output files must be within the package: ${JSON.stringify(
pathlib.join(rig.temp, 'outside'),
)} was outside ${JSON.stringify(pathlib.join(rig.temp, 'foo'))}