Use manifests for external cache to avoid overfetching
This commit is contained in:
parent
74154140df
commit
3c0903ad5b
10 changed files with 3105 additions and 131 deletions
13
README.md
13
README.md
|
|
@ -53,13 +53,13 @@ Default [`${{ github.token }}`][5].
|
||||||
### Simple configuration
|
### Simple configuration
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: p0deje/setup-bazel@0.1.0
|
- uses: p0deje/setup-bazel@0.2.0
|
||||||
```
|
```
|
||||||
|
|
||||||
### Additional `.bazelrc` options
|
### Additional `.bazelrc` options
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: p0deje/setup-bazel@0.1.0
|
- uses: p0deje/setup-bazel@0.2.0
|
||||||
with:
|
with:
|
||||||
bazelrc: |
|
bazelrc: |
|
||||||
build --show_timestamps
|
build --show_timestamps
|
||||||
|
|
@ -68,7 +68,7 @@ Default [`${{ github.token }}`][5].
|
||||||
### Full caching enabled
|
### Full caching enabled
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: p0deje/setup-bazel@0.1.0
|
- uses: p0deje/setup-bazel@0.2.0
|
||||||
with:
|
with:
|
||||||
bazelisk-cache: true
|
bazelisk-cache: true
|
||||||
disk-cache: true
|
disk-cache: true
|
||||||
|
|
@ -79,7 +79,7 @@ Default [`${{ github.token }}`][5].
|
||||||
### Separate disk cache between workflows
|
### Separate disk cache between workflows
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: p0deje/setup-bazel@0.1.0
|
- uses: p0deje/setup-bazel@0.2.0
|
||||||
with:
|
with:
|
||||||
disk-cache: ${{ github.workflow }}}
|
disk-cache: ${{ github.workflow }}}
|
||||||
```
|
```
|
||||||
|
|
@ -87,10 +87,11 @@ Default [`${{ github.token }}`][5].
|
||||||
### Cache external repository based on different files
|
### Cache external repository based on different files
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: p0deje/setup-bazel@0.1.0
|
- uses: p0deje/setup-bazel@0.2.0
|
||||||
with:
|
with:
|
||||||
external-cache: |
|
external-cache: |
|
||||||
npm: package-lock.json
|
manifest:
|
||||||
|
npm: package-lock.json
|
||||||
```
|
```
|
||||||
|
|
||||||
[1]: https://github.com/bazelbuild/bazelisk
|
[1]: https://github.com/bazelbuild/bazelisk
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,6 @@ inputs:
|
||||||
description: Cache repositories based on WORKSPACE
|
description: Cache repositories based on WORKSPACE
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
token:
|
|
||||||
description: GitHub token to use for external cache
|
|
||||||
required: false
|
|
||||||
default: ${{ github.token }}
|
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: node16
|
using: node16
|
||||||
|
|
|
||||||
37
config.js
37
config.js
|
|
@ -2,6 +2,7 @@ const fs = require('fs')
|
||||||
const os = require('os')
|
const os = require('os')
|
||||||
const yaml = require('yaml')
|
const yaml = require('yaml')
|
||||||
const core = require('@actions/core')
|
const core = require('@actions/core')
|
||||||
|
const github = require('@actions/github')
|
||||||
|
|
||||||
const cacheVersion = core.getInput('cache-version')
|
const cacheVersion = core.getInput('cache-version')
|
||||||
const externalCacheConfig = yaml.parse(core.getInput('external-cache'))
|
const externalCacheConfig = yaml.parse(core.getInput('external-cache'))
|
||||||
|
|
@ -57,29 +58,38 @@ if (googleCredentials.length > 0 && !googleCredentialsSaved) {
|
||||||
const bazelExternal = core.toPosixPath(`${bazelOutputBase}/external`)
|
const bazelExternal = core.toPosixPath(`${bazelOutputBase}/external`)
|
||||||
const externalCache = {}
|
const externalCache = {}
|
||||||
if (externalCacheConfig) {
|
if (externalCacheConfig) {
|
||||||
|
const { workflow, job } = github.context
|
||||||
|
const manifestName = externalCacheConfig.name ||
|
||||||
|
`${workflow.toLowerCase().replaceAll(/[ /]/g, '-')}-${job}`
|
||||||
|
|
||||||
externalCache.enabled = true
|
externalCache.enabled = true
|
||||||
externalCache.minSize = 10 // MB
|
externalCache.minSize = 10 // MB
|
||||||
externalCache.baseCacheKey = `${baseCacheKey}-external-`
|
externalCache.baseCacheKey = `${baseCacheKey}-external-`
|
||||||
externalCache.regexp = `^${baseCacheKey}-external-(?<name>.+)-[a-z0-9]+$`
|
externalCache.manifest = {
|
||||||
|
files: [
|
||||||
|
'WORKSPACE.bazel',
|
||||||
|
'WORKSPACE'
|
||||||
|
],
|
||||||
|
name: `external-${manifestName}-manifest`,
|
||||||
|
path: `${os.tmpdir()}/external-cache-manifest.txt`
|
||||||
|
}
|
||||||
externalCache.default = {
|
externalCache.default = {
|
||||||
files: [
|
files: [
|
||||||
'WORKSPACE.bazel',
|
'WORKSPACE.bazel',
|
||||||
'WORKSPACE'
|
'WORKSPACE'
|
||||||
]
|
],
|
||||||
}
|
name: (name) => { return `external-${name}` },
|
||||||
externalCache.name = (name) => {
|
paths: (name) => {
|
||||||
return `external-${name}`
|
return [
|
||||||
}
|
`${bazelExternal}/@${name}.marker`,
|
||||||
externalCache.paths = (name) => {
|
`${bazelExternal}/${name}`
|
||||||
return [
|
]
|
||||||
`${bazelExternal}/@${name}.marker`,
|
}
|
||||||
`${bazelExternal}/${name}`
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const name in externalCacheConfig) {
|
for (const name in externalCacheConfig.manifest) {
|
||||||
externalCache[name] = {
|
externalCache[name] = {
|
||||||
files: Array(externalCacheConfig[name]).flat()
|
files: Array(externalCacheConfig.manifest[name]).flat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -118,5 +128,4 @@ module.exports = {
|
||||||
name: 'repository',
|
name: 'repository',
|
||||||
paths: [bazelRepository]
|
paths: [bazelRepository]
|
||||||
},
|
},
|
||||||
token: core.getInput('token')
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
98
dist/main/index.js
vendored
98
dist/main/index.js
vendored
|
|
@ -8,6 +8,7 @@ const fs = __nccwpck_require__(7147)
|
||||||
const os = __nccwpck_require__(2037)
|
const os = __nccwpck_require__(2037)
|
||||||
const yaml = __nccwpck_require__(4083)
|
const yaml = __nccwpck_require__(4083)
|
||||||
const core = __nccwpck_require__(2186)
|
const core = __nccwpck_require__(2186)
|
||||||
|
const github = __nccwpck_require__(5438)
|
||||||
|
|
||||||
const cacheVersion = core.getInput('cache-version')
|
const cacheVersion = core.getInput('cache-version')
|
||||||
const externalCacheConfig = yaml.parse(core.getInput('external-cache'))
|
const externalCacheConfig = yaml.parse(core.getInput('external-cache'))
|
||||||
|
|
@ -63,29 +64,38 @@ if (googleCredentials.length > 0 && !googleCredentialsSaved) {
|
||||||
const bazelExternal = core.toPosixPath(`${bazelOutputBase}/external`)
|
const bazelExternal = core.toPosixPath(`${bazelOutputBase}/external`)
|
||||||
const externalCache = {}
|
const externalCache = {}
|
||||||
if (externalCacheConfig) {
|
if (externalCacheConfig) {
|
||||||
|
const { workflow, job } = github.context
|
||||||
|
const manifestName = externalCacheConfig.name ||
|
||||||
|
`${workflow.toLowerCase().replaceAll(/[ /]/g, '-')}-${job}`
|
||||||
|
|
||||||
externalCache.enabled = true
|
externalCache.enabled = true
|
||||||
externalCache.minSize = 10 // MB
|
externalCache.minSize = 10 // MB
|
||||||
externalCache.baseCacheKey = `${baseCacheKey}-external-`
|
externalCache.baseCacheKey = `${baseCacheKey}-external-`
|
||||||
externalCache.regexp = `^${baseCacheKey}-external-(?<name>.+)-[a-z0-9]+$`
|
externalCache.manifest = {
|
||||||
|
files: [
|
||||||
|
'WORKSPACE.bazel',
|
||||||
|
'WORKSPACE'
|
||||||
|
],
|
||||||
|
name: `external-${manifestName}-manifest`,
|
||||||
|
path: `${os.tmpdir()}/external-cache-manifest.txt`
|
||||||
|
}
|
||||||
externalCache.default = {
|
externalCache.default = {
|
||||||
files: [
|
files: [
|
||||||
'WORKSPACE.bazel',
|
'WORKSPACE.bazel',
|
||||||
'WORKSPACE'
|
'WORKSPACE'
|
||||||
]
|
],
|
||||||
}
|
name: (name) => { return `external-${name}` },
|
||||||
externalCache.name = (name) => {
|
paths: (name) => {
|
||||||
return `external-${name}`
|
return [
|
||||||
}
|
`${bazelExternal}/@${name}.marker`,
|
||||||
externalCache.paths = (name) => {
|
`${bazelExternal}/${name}`
|
||||||
return [
|
]
|
||||||
`${bazelExternal}/@${name}.marker`,
|
}
|
||||||
`${bazelExternal}/${name}`
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const name in externalCacheConfig) {
|
for (const name in externalCacheConfig.manifest) {
|
||||||
externalCache[name] = {
|
externalCache[name] = {
|
||||||
files: Array(externalCacheConfig[name]).flat()
|
files: Array(externalCacheConfig.manifest[name]).flat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +134,6 @@ module.exports = {
|
||||||
name: 'repository',
|
name: 'repository',
|
||||||
paths: [bazelRepository]
|
paths: [bazelRepository]
|
||||||
},
|
},
|
||||||
token: core.getInput('token')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -66132,14 +66141,6 @@ module.exports = require("net");
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
/***/ 9397:
|
|
||||||
/***/ ((module) => {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
module.exports = require("node:timers/promises");
|
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
|
|
||||||
/***/ 2037:
|
/***/ 2037:
|
||||||
/***/ ((module) => {
|
/***/ ((module) => {
|
||||||
|
|
||||||
|
|
@ -74616,10 +74617,8 @@ var __webpack_exports__ = {};
|
||||||
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
||||||
(() => {
|
(() => {
|
||||||
const fs = __nccwpck_require__(7147)
|
const fs = __nccwpck_require__(7147)
|
||||||
const { setTimeout } = __nccwpck_require__(9397)
|
|
||||||
const core = __nccwpck_require__(2186)
|
const core = __nccwpck_require__(2186)
|
||||||
const cache = __nccwpck_require__(7799)
|
const cache = __nccwpck_require__(7799)
|
||||||
const github = __nccwpck_require__(5438)
|
|
||||||
const glob = __nccwpck_require__(8090)
|
const glob = __nccwpck_require__(8090)
|
||||||
const config = __nccwpck_require__(5532)
|
const config = __nccwpck_require__(5532)
|
||||||
|
|
||||||
|
|
@ -74661,34 +74660,27 @@ async function restoreExternalCaches (cacheConfig) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const repo = github.context.repo
|
// First fetch the manifest of external caches used.
|
||||||
const octokit = github.getOctokit(config.token)
|
const path = cacheConfig.manifest.path
|
||||||
const { data: { actions_caches: caches } } = await octokit.rest.actions.getActionsCacheList({
|
await restoreCache({
|
||||||
owner: repo.owner,
|
enabled: true,
|
||||||
repo: repo.repo,
|
files: cacheConfig.manifest.files,
|
||||||
key: cacheConfig.baseCacheKey,
|
name: cacheConfig.manifest.name,
|
||||||
per_page: 100
|
paths: [path]
|
||||||
})
|
})
|
||||||
|
|
||||||
const names = new Set([])
|
// Now restore all external caches defined in manifest
|
||||||
const regexp = new RegExp(cacheConfig.regexp)
|
if (fs.existsSync(path)) {
|
||||||
for (const cache of caches) {
|
const manifest = fs.readFileSync(path, { encoding: 'utf8' })
|
||||||
core.debug(`Cache key is ${cache.key}`)
|
for (const name of manifest.split('\n').filter(s => s)) {
|
||||||
|
await restoreCache({
|
||||||
const match = cache.key.match(regexp)
|
enabled: true,
|
||||||
if (match) {
|
files: cacheConfig[name]?.files || cacheConfig.default.files,
|
||||||
names.add(match.groups.name)
|
name: cacheConfig.default.name(name),
|
||||||
|
paths: cacheConfig.default.paths(name)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const name of names) {
|
|
||||||
await restoreCache({
|
|
||||||
enabled: true,
|
|
||||||
files: cacheConfig[name]?.files || cacheConfig.default.files,
|
|
||||||
name: cacheConfig.name(name),
|
|
||||||
paths: cacheConfig.paths(name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function restoreCache (cacheConfig) {
|
async function restoreCache (cacheConfig) {
|
||||||
|
|
@ -74706,12 +74698,10 @@ async function restoreCache (cacheConfig) {
|
||||||
|
|
||||||
console.log(`Attempting to restore ${name} cache from ${key}`)
|
console.log(`Attempting to restore ${name} cache from ${key}`)
|
||||||
|
|
||||||
const restoredKey = await setTimeout(1000, async function() {
|
const restoredKey = await cache.restoreCache(
|
||||||
return await cache.restoreCache(
|
paths, key, [restoreKey],
|
||||||
paths, key, [restoreKey],
|
{ segmentTimeoutInMs: 300000 } // 5 minutes
|
||||||
{ segmentTimeoutInMs: 300000 } // 5 minutes
|
)
|
||||||
)
|
|
||||||
}())
|
|
||||||
|
|
||||||
if (restoredKey) {
|
if (restoredKey) {
|
||||||
console.log(`Successfully restored cache from ${restoredKey}`)
|
console.log(`Successfully restored cache from ${restoredKey}`)
|
||||||
|
|
|
||||||
2
dist/main/index.js.map
vendored
2
dist/main/index.js.map
vendored
File diff suppressed because one or more lines are too long
3007
dist/post/index.js
vendored
3007
dist/post/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/post/index.js.map
vendored
2
dist/post/index.js.map
vendored
File diff suppressed because one or more lines are too long
53
index.js
53
index.js
|
|
@ -1,8 +1,6 @@
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const { setTimeout } = require('node:timers/promises')
|
|
||||||
const core = require('@actions/core')
|
const core = require('@actions/core')
|
||||||
const cache = require('@actions/cache')
|
const cache = require('@actions/cache')
|
||||||
const github = require('@actions/github')
|
|
||||||
const glob = require('@actions/glob')
|
const glob = require('@actions/glob')
|
||||||
const config = require('./config')
|
const config = require('./config')
|
||||||
|
|
||||||
|
|
@ -44,34 +42,27 @@ async function restoreExternalCaches (cacheConfig) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const repo = github.context.repo
|
// First fetch the manifest of external caches used.
|
||||||
const octokit = github.getOctokit(config.token)
|
const path = cacheConfig.manifest.path
|
||||||
const { data: { actions_caches: caches } } = await octokit.rest.actions.getActionsCacheList({
|
await restoreCache({
|
||||||
owner: repo.owner,
|
enabled: true,
|
||||||
repo: repo.repo,
|
files: cacheConfig.manifest.files,
|
||||||
key: cacheConfig.baseCacheKey,
|
name: cacheConfig.manifest.name,
|
||||||
per_page: 100
|
paths: [path]
|
||||||
})
|
})
|
||||||
|
|
||||||
const names = new Set([])
|
// Now restore all external caches defined in manifest
|
||||||
const regexp = new RegExp(cacheConfig.regexp)
|
if (fs.existsSync(path)) {
|
||||||
for (const cache of caches) {
|
const manifest = fs.readFileSync(path, { encoding: 'utf8' })
|
||||||
core.debug(`Cache key is ${cache.key}`)
|
for (const name of manifest.split('\n').filter(s => s)) {
|
||||||
|
await restoreCache({
|
||||||
const match = cache.key.match(regexp)
|
enabled: true,
|
||||||
if (match) {
|
files: cacheConfig[name]?.files || cacheConfig.default.files,
|
||||||
names.add(match.groups.name)
|
name: cacheConfig.default.name(name),
|
||||||
|
paths: cacheConfig.default.paths(name)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const name of names) {
|
|
||||||
await restoreCache({
|
|
||||||
enabled: true,
|
|
||||||
files: cacheConfig[name]?.files || cacheConfig.default.files,
|
|
||||||
name: cacheConfig.name(name),
|
|
||||||
paths: cacheConfig.paths(name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function restoreCache (cacheConfig) {
|
async function restoreCache (cacheConfig) {
|
||||||
|
|
@ -89,12 +80,10 @@ async function restoreCache (cacheConfig) {
|
||||||
|
|
||||||
console.log(`Attempting to restore ${name} cache from ${key}`)
|
console.log(`Attempting to restore ${name} cache from ${key}`)
|
||||||
|
|
||||||
const restoredKey = await setTimeout(1000, async function() {
|
const restoredKey = await cache.restoreCache(
|
||||||
return await cache.restoreCache(
|
paths, key, [restoreKey],
|
||||||
paths, key, [restoreKey],
|
{ segmentTimeoutInMs: 300000 } // 5 minutes
|
||||||
{ segmentTimeoutInMs: 300000 } // 5 minutes
|
)
|
||||||
)
|
|
||||||
}())
|
|
||||||
|
|
||||||
if (restoredKey) {
|
if (restoredKey) {
|
||||||
console.log(`Successfully restored cache from ${restoredKey}`)
|
console.log(`Successfully restored cache from ${restoredKey}`)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "setup-bazel",
|
"name": "setup-bazel",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"description": "Install and configure Bazel for GitHub Actions",
|
"description": "Install and configure Bazel for GitHub Actions",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"engines" : {
|
"engines" : {
|
||||||
|
|
|
||||||
18
post.js
18
post.js
|
|
@ -1,3 +1,4 @@
|
||||||
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const cache = require('@actions/cache')
|
const cache = require('@actions/cache')
|
||||||
const core = require('@actions/core')
|
const core = require('@actions/core')
|
||||||
|
|
@ -26,6 +27,7 @@ async function saveExternalCaches (cacheConfig) {
|
||||||
{ implicitDescendants: false }
|
{ implicitDescendants: false }
|
||||||
)
|
)
|
||||||
const externalPaths = await globber.glob()
|
const externalPaths = await globber.glob()
|
||||||
|
const savedCaches = []
|
||||||
|
|
||||||
for (const externalPath of externalPaths) {
|
for (const externalPath of externalPaths) {
|
||||||
const size = await getFolderSize(externalPath)
|
const size = await getFolderSize(externalPath)
|
||||||
|
|
@ -37,11 +39,23 @@ async function saveExternalCaches (cacheConfig) {
|
||||||
await saveCache({
|
await saveCache({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
files: cacheConfig[name]?.files || cacheConfig.default.files,
|
files: cacheConfig[name]?.files || cacheConfig.default.files,
|
||||||
name: cacheConfig.name(name),
|
name: cacheConfig.default.name(name),
|
||||||
paths: cacheConfig.paths(name)
|
paths: cacheConfig.default.paths(name)
|
||||||
})
|
})
|
||||||
|
savedCaches.push(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (savedCaches.length > 0) {
|
||||||
|
const path = cacheConfig.manifest.path
|
||||||
|
fs.writeFileSync(path, savedCaches.join('\n'))
|
||||||
|
await saveCache({
|
||||||
|
enabled: true,
|
||||||
|
files: cacheConfig.manifest.files,
|
||||||
|
name: cacheConfig.manifest.name,
|
||||||
|
paths: [path]
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveCache (cacheConfig) {
|
async function saveCache (cacheConfig) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue