Skip to content

Commit d57231c

Browse files
committed
Implement automatic bundle install and caching
* Not yet enabled by default.
1 parent 281d1c5 commit d57231c

File tree

6 files changed

+6188
-2512
lines changed

6 files changed

+6188
-2512
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ jobs:
3939
- uses: ./
4040
with:
4141
ruby-version: ${{ matrix.ruby }}
42+
bundler-cache: true
4243
- run: ruby -v
4344

4445
- name: build compiler

README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,27 @@ Otherwise, the latest Bundler version is installed (except for Ruby 2.2 and 2.3
116116

117117
This behavior can be customized, see [action.yml](action.yml) for details about the `bundler` input.
118118

119-
### Caching `bundle install`
119+
### Caching `bundle install` automatically
120120

121+
This action provides a way to automatically run `bundle install` and cache the result:
122+
```yaml
123+
- uses: ruby/setup-ruby@v1
124+
with:
125+
bundler-cache: true
126+
```
127+
128+
This caching speeds up installing gems significantly and avoids too many requests to RubyGems.org.
129+
It needs a `Gemfile` under the [`working-directory`](#working-directory).
130+
The caching works whether there is a `Gemfile.lock` or not.
131+
If there is a `Gemfile.lock`, `bundle config --local deployment true` is used.
132+
133+
To perform caching, this action will use `bundle config --local path vendor/bundle`.
134+
Therefore, the Bundler `path` should not be changed in your workflow for the cache to work.
135+
136+
### Caching `bundle install` manually
137+
138+
You can also cache gems manually,
139+
but this is not recommended because it is verbose and very difficult to use a correct cache key.
121140
You can cache the installed gems with these two steps:
122141

123142
```yaml
@@ -140,7 +159,8 @@ When using `.ruby-version`, replace `${{ matrix.ruby }}` with `${{ hashFiles('.r
140159
When using `.tool-versions`, replace `${{ matrix.ruby }}` with `${{ hashFiles('.tool-versions') }}`.
141160

142161
This uses the [cache action](https://github.com/actions/cache).
143-
The code above is a more complete version of the [Ruby - Bundler example](https://github.com/actions/cache/blob/master/examples.md#ruby---bundler).
162+
The code above is a more complete version of the [Ruby - Bundler example](https://github.com/actions/cache/blob/master/examples.md#ruby---\
163+
bundler).
144164
Make sure to include `use-ruby` in the `key` to avoid conflicting with previous caches.
145165

146166
### Working Directory

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ inputs:
1313
description: 'The version of Bundler to install. Either none, 1, 2, latest or Gemfile.lock. The default tries Gemfile.lock and otherwise uses latest.'
1414
required: false
1515
default: 'default'
16+
bundler-cache:
17+
description: 'Run "bundle install", and cache the result automatically. Either true or false.'
18+
required: false
19+
default: 'false'
1620
working-directory:
1721
description: 'The working directory to use for resolving paths for .ruby-version, .tool-versions and Gemfile.lock.'
1822
required: false

common.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
const os = require('os')
22
const fs = require('fs')
3+
const util = require('util')
4+
const stream = require('stream')
5+
const crypto = require('crypto')
36
const core = require('@actions/core')
47
const { performance } = require('perf_hooks')
58

@@ -20,6 +23,14 @@ export function isHeadVersion(rubyVersion) {
2023
return rubyVersion === 'head' || rubyVersion === 'debug' || rubyVersion === 'mingw' || rubyVersion === 'mswin'
2124
}
2225

26+
export async function hashFile(file) {
27+
// See https://github.com/actions/runner/blob/master/src/Misc/expressionFunc/hashFiles/src/hashFiles.ts
28+
const hash = crypto.createHash('sha256')
29+
const pipeline = util.promisify(stream.pipeline)
30+
await pipeline(fs.createReadStream(file), hash)
31+
return hash.digest('hex')
32+
}
33+
2334
export function getVirtualEnvironmentName() {
2435
const platform = os.platform()
2536
if (platform === 'linux') {

0 commit comments

Comments
 (0)