Skip to content

Commit

Permalink
Rework pacman pkg cache and enable by default
Browse files Browse the repository at this point in the history
Three main improvements:

* Create a separate cache for each input configuration: Assuming a build matrix
  which builds for different arches and has different dependencies we create
  a cache for each of them, while loading any of them.
* Prune caches before saving them: Every time a package has a new version we
  create a new cache which only includes the new packages. This makes sure that
  the cache/restore size stays as small as possible over time.
* Avoid cache race conditions: If a run doesn't change the cache we wont save it
  and if saving fails because another job created it in the mean time,
  we catch the error and ignore it.

Overall this cache doesn't save much time, since installation and initial setup
take the most time, but this should save a lot of traffic for our main
repo server.

And also this removes the cache option which was confusing some users because it
only caches packages and not everything.
  • Loading branch information
lazka committed Jul 19, 2020
1 parent d4d3756 commit cc801fa
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 34 deletions.
18 changes: 0 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,6 @@ Installing additional packages after updating the system is supported through op
install: 'git base-devel'
```

#### cache

If set to `true`, directory `/var/cache/pacman/pkg` is restored/cached in order to speed up future updates:

```yaml
- uses: msys2/setup-msys2@v1
with:
cache: true
```

If set to `save`, the same directory is cached, but it is not restored. This can be used to force a save of a clean state.

```yaml
- uses: msys2/setup-msys2@v1
with:
cache: save
```

## Development

The steps to publish a new release are the following:
Expand Down
4 changes: 0 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ inputs:
description: 'Install packages after installation through pacman'
required: false
default: false
cache:
description: 'Cache /var/cache/pacman/pkg to speed up future updates'
required: false
default: false
runs:
using: 'node12'
main: 'index.js'
47 changes: 35 additions & 12 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const exec = require('@actions/exec');
const tc = require('@actions/tool-cache');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const { hashElement } = require('folder-hash');

const inst_url = 'https://github.com/msys2/msys2-installer/releases/download/2020-06-29/msys2-base-x86_64-20200629.sfx.exe';
Expand Down Expand Up @@ -36,7 +37,6 @@ async function run() {
const p_pathtype = core.getInput('path-type');
const p_msystem = core.getInput('msystem');
const p_install = core.getInput('install');
const p_cache = core.getInput('cache');

let base = 'C:';

Expand Down Expand Up @@ -75,15 +75,22 @@ async function run() {
fs.writeFileSync(cmd, wrap);

core.addPath(dest);
const c_paths = [(p_release ? dest : 'C:') + `\\msys64\\var\\cache\\pacman\\pkg\\`];
const pkgCachePath = (p_release ? dest : 'C:') + `\\msys64\\var\\cache\\pacman\\pkg\\`;

core.exportVariable('MSYSTEM', p_msystem);

if (p_cache === 'true') {
core.startGroup('Restoring cache...');
console.log('Cache ID:', await cache.restoreCache(c_paths, 'msys2', ['msys2-']));
core.endGroup();
}
// We want a cache key that is ideally always the same for the same kind of job.
// So that mingw32 and ming64 jobs, and jobs with different install packages have different caches.
let shasum = crypto.createHash('sha1');
['release', 'update', 'path-type', 'msystem', 'install'].map((n) => { return shasum.update(core.getInput(n)); });
const baseCacheKey = 'msys2-pkgs';
const jobCacheKey = baseCacheKey + '-conf:' + shasum.digest('hex').slice(0, 8);

core.startGroup('Restoring cache...');
// We ideally want a cache matching our configuration, but every cache is OK since we prune it later anyway
const restoreKey = await cache.restoreCache([pkgCachePath], jobCacheKey, [jobCacheKey, baseCacheKey]);
console.log(`Cache restore for ${jobCacheKey}, got ${restoreKey}`);
core.endGroup();

async function run(args, opts) {
await exec.exec('cmd', ['/D', '/S', '/C', cmd].concat(['-c', args.join(' ')]), opts);
Expand Down Expand Up @@ -116,12 +123,28 @@ async function run() {
core.endGroup();
}

if (p_cache === 'true' || p_cache === 'save') {
core.startGroup('Saving cache...');
const key = (await hashElement(c_paths[0]))['hash'].toString() + (new Date()).getTime().toString();
console.log('Cache ID:', await cache.saveCache(c_paths, 'msys2-' + key), '[' + key + ']');
core.endGroup();
core.startGroup('Prune cache...');
// Remove all uninstalled packages
await run(['paccache', '-r', '-f', '-u', '-k0']);
// Keep the newest for all other packages
await run(['paccache', '-r', '-f', '-k1']);
core.endGroup();

core.startGroup('Saving cache...');
const saveKey = jobCacheKey + '-files:' + (await hashElement(pkgCachePath))['hash'].toString();
if (restoreKey === saveKey) {
console.log(`Cache unchanged, skipping save for ${saveKey}`);
} else {
try {
const cacheId = await cache.saveCache([pkgCachePath], saveKey);
console.log(`Cache saved as ID ${cacheId} using key ${saveKey}`);
} catch (error) {
// In case something created the same cache since we restored we'll get an error here,
// but that's OK with us, so ignore.
console.log(error.message);
}
}
core.endGroup();
}
catch (error) {
core.setFailed(error.message);
Expand Down

0 comments on commit cc801fa

Please sign in to comment.