Skip to content

Commit

Permalink
Add support for google/wireit@setup-github-actions-caching/v2 (#1147)
Browse files Browse the repository at this point in the history
Adds support for the `v2` version of the `google/wireit@setup-github-actions-caching` action, which provides improved security.
  • Loading branch information
aomarks committed Aug 5, 2024
1 parent 0e6a615 commit 75acfff
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 28 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 -->
## 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

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -857,7 +857,7 @@ The following environment variables affect the behavior of Wireit:
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WIREIT_FAILURES` | [How to handle script failures](#failures-and-errors).<br><br>Options:<br><ul><li>[`no-new`](#failures-and-errors) (default): Allow running scripts to finish, but don't start new ones.</li><li>[`continue`](#continue): Allow running scripts to continue, and start new ones unless any of their dependencies failed.</li><li>[`kill`](#kill): Immediately kill running scripts, and don't start new ones.</li></ul> |
| `WIREIT_PARALLEL` | [Maximum number of scripts to run at one time](#parallelism).<br><br>Defaults to 2×logical CPU cores.<br><br>Must be a positive integer or `infinity`. |
| `WIREIT_CACHE` | [Caching mode](#caching).<br><br>Defaults to `local` unless `CI` is `true`, in which case defaults to `none`.<br><br>Automatically set to `github` by the [`google/wireit@setup-github-actions-caching/v1`](#github-actions-caching) action.<br><br>Options:<ul><li>[`local`](#local-caching): Cache to local disk.</li><li>[`github`](#github-actions-caching): Cache to GitHub Actions.</li><li>`none`: Disable caching.</li></ul> |
| `WIREIT_CACHE` | [Caching mode](#caching).<br><br>Defaults to `local` unless `CI` is `true`, in which case defaults to `none`.<br><br>Automatically set to `github` by the [`google/wireit@setup-github-actions-caching/v2`](#github-actions-caching) action.<br><br>Options:<ul><li>[`local`](#local-caching): Cache to local disk.</li><li>[`github`](#github-actions-caching): Cache to GitHub Actions.</li><li>`none`: Disable caching.</li></ul> |
| `CI` | Affects the default value of `WIREIT_CACHE`.<br><br>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.<br><br>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.<br><br>Options:<br><ul><li>`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.</li><li>`simple` (default): A verbose logger that presents clear information about the work that Wireit is doing.</li><li>`metrics`: Like `simple`, but also presents a summary table of results once a command is finished.</li><li>`quiet-ci` (default when env.CI or !stdout.isTTY): like `quiet` but optimized for non-interactive environments, like GitHub Actions runners.</li></ul> |
Expand Down
79 changes: 77 additions & 2 deletions src/caching/github-actions-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -48,9 +49,80 @@ export class GitHubActionsCache implements Cache {
this.#logger = logger;
}

static create(
static async create(
logger: Logger,
): Result<GitHubActionsCache, {reason: 'invalid-usage'; message: string}> {
): Promise<
Result<
GitHubActionsCache,
Omit<InvalidUsage, 'script'> | Omit<UnknownErrorThrown, 'script'>
>
> {
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<GitHubActionsCache, Omit<InvalidUsage, 'script'>> {
// 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
Expand All @@ -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 ' +
Expand All @@ -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,
Expand All @@ -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 ' +
Expand Down
31 changes: 10 additions & 21 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,17 @@ const run = async (options: Options): Promise<Result<void, Failure[]>> => {
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;
Expand Down
2 changes: 1 addition & 1 deletion src/test/cache-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'))}
Expand Down

0 comments on commit 75acfff

Please sign in to comment.