@@ -75,25 +75,15 @@ export async function setupRuby(options = {}) {
7575 core . setOutput ( 'ruby-prefix' , rubyPrefix )
7676}
7777
78+ // The returned gemfile is guaranteed to exist, the lockfile might not exist
7879function detectGemfiles ( ) {
7980 const gemfilePath = process . env [ 'BUNDLE_GEMFILE' ] || 'Gemfile'
8081 if ( fs . existsSync ( gemfilePath ) ) {
81- const lockPath = `${ gemfilePath } .lock`
82- if ( fs . existsSync ( lockPath ) ) {
83- return [ gemfilePath , lockPath ]
84- } else {
85- return [ gemfilePath , null ]
86- }
82+ return [ gemfilePath , `${ gemfilePath } .lock` ]
8783 }
8884
89- const gemsRbPath = "gems.rb"
90- if ( fs . existsSync ( gemsRbPath ) ) {
91- const lockPath = "gems.locked"
92- if ( fs . existsSync ( lockPath ) ) {
93- return [ gemsRbPath , lockPath ]
94- } else {
95- return [ gemsRbPath , null ]
96- }
85+ if ( fs . existsSync ( "gems.rb" ) ) {
86+ return [ "gems.rb" , "gems.locked" ]
9787 }
9888
9989 return [ null , null ]
@@ -177,7 +167,7 @@ function envPreInstall() {
177167}
178168
179169function readBundledWithFromGemfileLock ( lockFile ) {
180- if ( lockFile !== null ) {
170+ if ( lockFile !== null && fs . existsSync ( lockFile ) ) {
181171 const contents = fs . readFileSync ( lockFile , 'utf8' )
182172 const lines = contents . split ( / \r ? \n / )
183173 const bundledWithLine = lines . findIndex ( line => / ^ B U N D L E D W I T H $ / . test ( line . trim ( ) ) )
@@ -245,24 +235,22 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
245235 // config
246236 const path = 'vendor/bundle'
247237
248- if ( lockFile !== null ) {
238+ await exec . exec ( 'bundle' , [ 'config' , '--local' , 'path' , path ] )
239+
240+ if ( fs . existsSync ( lockFile ) ) {
249241 await exec . exec ( 'bundle' , [ 'config' , '--local' , 'deployment' , 'true' ] )
242+ } else {
243+ // Generate the lockfile so we can use it to compute the cache key.
244+ // This will also automatically pick up the latest gem versions compatible with the Gemfile.
245+ await exec . exec ( 'bundle' , [ 'lock' ] )
250246 }
251- await exec . exec ( 'bundle' , [ 'config' , '--local' , 'path' , path ] )
252247
253248 // cache key
254249 const paths = [ path ]
255- const baseKey = await computeBaseKey ( platform , engine , version , gemfile )
256- let key = baseKey
257- let restoreKeys
258- if ( lockFile !== null ) {
259- key += `-${ lockFile } -${ await common . hashFile ( lockFile ) } `
260- // If only Gemfile.lock changes we can reuse part of the cache (but it will keep old gem versions in the cache)
261- restoreKeys = [ `${ baseKey } -${ lockFile } -` ]
262- } else {
263- // Only exact key, to never mix native gems of different platforms or Ruby versions
264- restoreKeys = [ ]
265- }
250+ const baseKey = await computeBaseKey ( platform , engine , version , lockFile )
251+ const key = `${ baseKey } -${ await common . hashFile ( lockFile ) } `
252+ // If only Gemfile.lock changes we can reuse part of the cache (but it will keep old gem versions in the cache)
253+ const restoreKeys = [ `${ baseKey } -` ]
266254 console . log ( `Cache key: ${ key } ` )
267255
268256 // restore cache & install
@@ -281,15 +269,11 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
281269 console . log ( `Found cache for key: ${ cachedKey } ` )
282270 }
283271
284- let alreadyInstalled = false
285- if ( cachedKey === key ) {
286- const exitCode = await exec . exec ( 'bundle' , [ 'check' ] , { ignoreReturnCode : true } )
287- alreadyInstalled = ( exitCode === 0 )
288- }
289-
290- if ( ! alreadyInstalled ) {
291- await exec . exec ( 'bundle' , [ 'install' , '--jobs' , '4' ] )
272+ // Always run 'bundle install' to list the gems
273+ await exec . exec ( 'bundle' , [ 'install' , '--jobs' , '4' ] )
292274
275+ // @actions /cache only allows to save for non-existing keys
276+ if ( cachedKey !== key ) {
293277 // Error handling from https://github.com/actions/cache/blob/master/src/save.ts
294278 console . log ( 'Saving cache' )
295279 try {
@@ -308,8 +292,9 @@ async function bundleInstall(gemfile, lockFile, platform, engine, version) {
308292 return true
309293}
310294
311- async function computeBaseKey ( platform , engine , version , gemfile ) {
312- let baseKey = `setup-ruby-toolcache-bundle-install-${ platform } -${ engine } -${ version } -${ gemfile } `
295+ async function computeBaseKey ( platform , engine , version , lockFile ) {
296+ let key = `setup-ruby-bundler-cache-v2-${ platform } -${ engine } -${ version } `
297+
313298 if ( engine !== 'jruby' && common . isHeadVersion ( version ) ) {
314299 let revision = '' ;
315300 await exec . exec ( 'ruby' , [ '-e' , 'print RUBY_REVISION' ] , {
@@ -320,9 +305,11 @@ async function computeBaseKey(platform, engine, version, gemfile) {
320305 }
321306 }
322307 } ) ;
323- baseKey += `-revision-${ revision } `
308+ key += `-revision-${ revision } `
324309 }
325- return baseKey
310+
311+ key += `-${ lockFile } `
312+ return key
326313}
327314
328315if ( __filename . endsWith ( 'index.js' ) ) { run ( ) }
0 commit comments