Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ It is also possible to cache gems manually, but this is not recommended because
There are many concerns which means using `actions/cache` is never enough for caching gems (e.g., incomplete cache key, cleaning old gems when restoring from another key, correctly hashing the lockfile if not checked in, OS versions, ABI compatibility for `ruby-head`, etc).
So, please use `bundler-cache: true` instead and report any issue.

#### Caching with an ephemeral working directory

A runner could be set up to use an ephemeral working directory per build, e.g. `/codebuild/output/src3500696690/src/actions-runner/_work/my-project`.
By default, the cache key includes the full working directory path; but for an ephemeral working directory, it wouldn't produce the same key across runs, resulting in an inability to restore from the cache.
To resolve this, set the `project-id` option to a name to identify your project. When provided, this is used instead of the working directory path in the cache key.

```yaml
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
project-id: my-project
```

### Authentication Token

By default, this action uses `${{ github.token }}` to authenticate when downloading Ruby release assets from GitHub.
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ inputs:
When running this action on github.com, the default value is sufficient.
When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting.
default: ${{ github.server_url == 'https://github.com' && github.token || '' }}
project-id:
description: |
A name to identify your project, for inclusion in the Bundler cache key instead of the full working directory path.
Useful when your runner is set up to use an ephemeral working directory per build.

outputs:
ruby-prefix:
Expand Down
10 changes: 5 additions & 5 deletions bundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ function bundlerConfigSetArgs(bundlerVersion, key, value) {
}
}

export async function bundleInstall(gemfile, lockFile, platform, engine, rubyVersion, bundlerVersion, cacheVersion) {
export async function bundleInstall(gemfile, lockFile, platform, engine, rubyVersion, bundlerVersion, cacheVersion, projectId) {
if (gemfile === null) {
console.log('Could not determine gemfile path, skipping "bundle install" and caching')
return false
Expand Down Expand Up @@ -189,7 +189,7 @@ export async function bundleInstall(gemfile, lockFile, platform, engine, rubyVer

// cache key
const paths = [cachePath]
const baseKey = await computeBaseKey(engine, rubyVersion, lockFile, cacheVersion)
const baseKey = await computeBaseKey(engine, rubyVersion, lockFile, cacheVersion, projectId)
const key = `${baseKey}-${await common.hashFile(lockFile)}`
// If only Gemfile.lock changes we can reuse part of the cache, and clean old gem versions below
const restoreKeys = [`${baseKey}-`]
Expand Down Expand Up @@ -242,12 +242,12 @@ export async function bundleInstall(gemfile, lockFile, platform, engine, rubyVer
return true
}

async function computeBaseKey(engine, version, lockFile, cacheVersion) {
const cwd = process.cwd()
async function computeBaseKey(engine, version, lockFile, cacheVersion, specifiedProjectId) {
const projectId = specifiedProjectId || `wd-${process.cwd()}`
const bundleWith = process.env['BUNDLE_WITH'] || ''
const bundleWithout = process.env['BUNDLE_WITHOUT'] || ''
const bundleOnly = process.env['BUNDLE_ONLY'] || ''
let key = `setup-ruby-bundler-cache-v6-${common.getOSNameVersionArch()}-${engine}-${version}-wd-${cwd}-with-${bundleWith}-without-${bundleWithout}-only-${bundleOnly}`
let key = `setup-ruby-bundler-cache-v6-${common.getOSNameVersionArch()}-${engine}-${version}-${projectId}-with-${bundleWith}-without-${bundleWithout}-only-${bundleOnly}`

if (cacheVersion !== DEFAULT_CACHE_VERSION) {
key += `-v-${cacheVersion}`
Expand Down
13 changes: 7 additions & 6 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const inputDefaults = {
'self-hosted': 'false',
'windows-toolchain': 'default',
'token': '',
'project-id': null,
}

// entry point when this action is run on its own
Expand Down Expand Up @@ -100,7 +101,7 @@ export async function setupRuby(options = {}) {

if (inputs['bundler-cache'] === 'true') {
await common.time('bundle install', async () =>
bundler.bundleInstall(gemfile, lockFile, platform, engine, version, bundlerVersion, inputs['cache-version']))
bundler.bundleInstall(gemfile, lockFile, platform, engine, version, bundlerVersion, inputs['cache-version'], inputs['project-id']))
}

core.setOutput('ruby-prefix', rubyPrefix)
Expand Down