Skip to content
Merged
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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,20 @@ When there is no lockfile, one is generated with `bundle lock`, which is the sam
In other words, it works exactly like `bundle install`.
The hash of the generated lockfile is then used for caching, which is the only correct approach.

#### Dealing with a corrupted cache

In some rare scenarios (like using gems with C extensions whose functionality depends on libraries found on the system
at the time of the gem's build) it may be necessary to ignore contents of the cache and get and build all the gems anew.
In order to achieve this, set the `cache-version` option to any value other than `0` (or change it to a new unique value
if you have already used it before.)

```yaml
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
cache-version: 1
```

#### Caching `bundle install` manually

It is also possible to cache gems manually, but this is not recommended because it is verbose and *very difficult* to do correctly.
Expand Down
6 changes: 6 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ inputs:
description: 'The working directory to use for resolving paths for .ruby-version, .tool-versions and Gemfile.lock.'
required: false
default: '.'
cache-version:
description: |
Arbitrary string that will be added to the cache key of the bundler cache. Set or change it if you need
to invalidate the cache.
required: false
default: '0'
outputs:
ruby-prefix:
description: 'The prefix of the installed ruby'
Expand Down
11 changes: 7 additions & 4 deletions bundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const exec = require('@actions/exec')
const cache = require('@actions/cache')
const common = require('./common')

export const DEFAULT_CACHE_VERSION = '0'

// The returned gemfile is guaranteed to exist, the lockfile might not exist
export function detectGemfiles() {
const gemfilePath = process.env['BUNDLE_GEMFILE'] || 'Gemfile'
Expand Down Expand Up @@ -95,7 +97,7 @@ export async function installBundler(bundlerVersionInput, lockFile, platform, ru
return bundlerVersion
}

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

// cache key
const paths = [cachePath]
const baseKey = await computeBaseKey(platform, engine, rubyVersion, lockFile)
const baseKey = await computeBaseKey(platform, engine, rubyVersion, lockFile, cacheVersion)
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 @@ -177,8 +179,9 @@ export async function bundleInstall(gemfile, lockFile, platform, engine, rubyVer
return true
}

async function computeBaseKey(platform, engine, version, lockFile) {
let key = `setup-ruby-bundler-cache-v3-${platform}-${engine}-${version}`
async function computeBaseKey(platform, engine, version, lockFile, cacheVersion) {
const cacheVersionSuffix = DEFAULT_CACHE_VERSION === cacheVersion ? '' : `-cachever:${cacheVersion}`
let key = `setup-ruby-bundler-cache-v3-${platform}-${engine}-${version}${cacheVersionSuffix}`

if (engine !== 'jruby' && common.isHeadVersion(version)) {
let revision = '';
Expand Down
15 changes: 10 additions & 5 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 @@ -12,6 +12,7 @@ const inputDefaults = {
'bundler': 'default',
'bundler-cache': 'true',
'working-directory': '.',
'cache-version': bundler.DEFAULT_CACHE_VERSION,
}

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

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

Expand Down