Skip to content

Commit

Permalink
run-vcpkg@v11: leverage BinaryCaching with GH Action's cache.
Browse files Browse the repository at this point in the history
  • Loading branch information
lukka committed Mar 31, 2023
1 parent 12bbe97 commit ec2db93
Show file tree
Hide file tree
Showing 14 changed files with 5,624 additions and 3,339 deletions.
13 changes: 6 additions & 7 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,16 @@ jobs:
uses: ./
with:
vcpkgDirectory: ${{ github.workspace }}/vcpkg
vcpkgGitCommitId: '14e7bb4ae24616ec54ff6b2f6ef4e8659434ea44'
vcpkgGitCommitId: 'c9f906558f9bb12ee9811d6edc98ec9255c6cda5'
vcpkgGitUrl: 'https://github.com/microsoft/vcpkg.git'

- name: basic test for run-vcpkg with running 'vcpkg install'.
uses: ./
with:
vcpkgDirectory: ${{ github.workspace }}/vcpkg
vcpkgGitCommitId: '14e7bb4ae24616ec54ff6b2f6ef4e8659434ea44'
vcpkgGitCommitId: 'c9f906558f9bb12ee9811d6edc98ec9255c6cda5'
runVcpkgInstall: true
# This forces the creation of a new cache entry each time the workflow is run.
# It is the same across jobs in the same workflows.
prependedCacheKey: ${{ env.GITHUB_RUN_ID }}
vcpkgGitUrl: 'https://github.com/microsoft/vcpkg.git'
env:
VCPKG_INSTALLED_DIR: ${{ github.workspace }}/vcpkg_installed

Expand All @@ -91,8 +90,8 @@ jobs:
uses: ./
with:
vcpkgDirectory: ${{ github.workspace }}/vcpkg
vcpkgGitCommitId: '14e7bb4ae24616ec54ff6b2f6ef4e8659434ea44'
prependedCacheKey: ${{ env.GITHUB_RUN_ID }}
vcpkgGitCommitId: 'c9f906558f9bb12ee9811d6edc98ec9255c6cda5'
vcpkgGitUrl: 'https://github.com/microsoft/vcpkg.git'

finalize_coveralls:
needs: build_and_unit_test
Expand Down
130 changes: 55 additions & 75 deletions README.md

Large diffs are not rendered by default.

24 changes: 17 additions & 7 deletions __tests__/functional.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021-2022 Luca Cappa
// Copyright (c) 2021-2022-2023 Luca Cappa
// Released under the term specified in file LICENSE.txt
// SPDX short identifier: MIT

Expand All @@ -24,6 +24,9 @@ const baseLibUtils = new BaseUtilLib(actionLib);
describe('run-vcpkg functional tests', () => {
beforeEach(async () => {
process.env.GITHUB_WORKSPACE = assetDirectory;
// The GH Action cache is not enabled when running tests because these env vars are not defined:
// ACTIONS_RUNTIME_TOKEN and ACTIONS_CACHE_URL. Set a default that uses the filesystem and won't fail.
process.env.VCPKG_BINARY_SOURCES = 'clear;default,readwrite';

await actionLib.rmRF(vcpkgDirectory);
await actionLib.rmRF(tempDirectory);
Expand All @@ -46,12 +49,16 @@ describe('run-vcpkg functional tests', () => {
}, 100000);

test('vcpkg setup and install must succeed', () => {
process.env.INPUT_VCPKGGITURL = "https://github.com/microsoft/vcpkg.git";
process.env.INPUT_VCPKGDIRECTORY = vcpkgDirectory;
process.env.INPUT_VCPKGJSONGLOB = "**/vcpkg.json";
process.env.INPUT_VCPKGGITCOMMITID = "6ca56aeb457f033d344a7106cb3f9f1abf8f4e98";
process.env.INPUT_VCPKGGITCOMMITID = "c9f906558f9bb12ee9811d6edc98ec9255c6cda5";
process.env.INPUT_RUNVCPKGINSTALL = "true";
process.env.INPUT_RUNVCPKGFORMATSTRING = runvcpkglib.VcpkgRunner.VCPKGINSTALLCMDDEFAULT;

// Ensure child is running in the GH workspace, needed to find vcpkg.json.
process.chdir(vcpkgProject);

const options: cp.ExecSyncOptions = {
env: process.env,
stdio: "inherit"
Expand All @@ -60,9 +67,10 @@ describe('run-vcpkg functional tests', () => {
});

test('vcpkg setup and no install must succeed', () => {
process.env.INPUT_VCPKGGITURL = "https://github.com/microsoft/vcpkg.git";
process.env.INPUT_VCPKGDIRECTORY = vcpkgDirectory;
process.env.INPUT_VCPKGJSONGLOB = "**/vcpkg.json";
process.env.INPUT_VCPKGGITCOMMITID = "6ca56aeb457f033d344a7106cb3f9f1abf8f4e98";
process.env.INPUT_VCPKGGITCOMMITID = "c9f906558f9bb12ee9811d6edc98ec9255c6cda5";
process.env.INPUT_RUNVCPKGINSTALL = "false";
process.env.INPUT_RUNVCPKGFORMATSTRING = "['invalid command']";

Expand All @@ -77,7 +85,8 @@ describe('run-vcpkg functional tests', () => {
delete process.env.INPUT_VCPKGDIRECTORY;
console.log(process.env.INPUT_VCPKGDIRECTORY);
delete process.env.INPUT_VCPKGJSONGLOB;
process.env.INPUT_VCPKGGITCOMMITID = "6ca56aeb457f033d344a7106cb3f9f1abf8f4e98";
process.env.INPUT_VCPKGGITURL = "https://github.com/microsoft/vcpkg.git";
process.env.INPUT_VCPKGGITCOMMITID = "c9f906558f9bb12ee9811d6edc98ec9255c6cda5";
process.env.INPUT_RUNVCPKGINSTALL = "false";
process.env.INPUT_RUNVCPKGFORMATSTRING = runvcpkglib.VcpkgRunner.VCPKGINSTALLCMDDEFAULT;

Expand All @@ -101,8 +110,9 @@ describe('run-vcpkg functional tests', () => {
await actionLib.rmRF(await runvcpkglib.getDefaultVcpkgDirectory(baseLibUtils.baseLib));
await actionLib.rmRF(await runvcpkglib.getDefaultVcpkgInstallDirectory(baseLibUtils.baseLib));
await actionLib.rmRF(await runvcpkglib.getDefaultVcpkgCacheDirectory(baseLibUtils.baseLib));

process.env.INPUT_VCPKGGITCOMMITID = "6ca56aeb457f033d344a7106cb3f9f1abf8f4e98";

process.env.INPUT_VCPKGGITURL = "https://github.com/microsoft/vcpkg.git";
process.env.INPUT_VCPKGGITCOMMITID = "c9f906558f9bb12ee9811d6edc98ec9255c6cda5";
process.env.INPUT_RUNVCPKGINSTALL = "true";
process.env.INPUT_RUNVCPKGFORMATSTRING = runvcpkglib.VcpkgRunner.VCPKGINSTALLCMDDEFAULT;

Expand All @@ -124,7 +134,7 @@ describe('run-vcpkg functional tests', () => {
console.log(cp.execSync(`node ${testScript}`, options)?.toString());
const elapsedWithInstalled = new Date().getTime() - startTime.getTime();
console.log(`********* With vcpkg_installed it took: ${elapsedWithInstalled}ms`)
expect(elapsedWithInstalled).toBeLessThan(elapsed / 3);
expect(elapsedWithInstalled).toBeLessThan((elapsed / 3) + 5000);// Allow 5 seconds of abs err.

// Consume the generated cache, and it should take considerably less than without cache.
await actionLib.rmRF(await runvcpkglib.getDefaultVcpkgInstallDirectory(baseLibUtils.baseLib));
Expand Down
129 changes: 23 additions & 106 deletions __tests__/unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Copyright (c) 2020-2021-2022-2023 Luca Cappa
// Released under the term specified in file LICENSE.txt
// SPDX short identifier: MIT

import * as process from 'process'
import * as fs from 'fs'
import * as os from 'os'
Expand All @@ -8,12 +12,8 @@ import * as runvcpkglib from '@lukka/run-vcpkg-lib'
import * as path from 'path'
import * as baseutil from '@lukka/base-util-lib'
import * as vcpkgutils from '../src/vcpkg-utils'
import * as core from '@actions/core'
import * as vcpkgpostaction from '../src/vcpkg-post-action'

jest.setTimeout(15 * 1000);
// Mocks entire action-lib module.
//??jest.mock("@lukka/action-lib");
jest.setTimeout(120 * 1000);
const baseUtil = new baseutil.BaseUtilLib(new actionlib.ActionLib());
let warningMock: jest.SpyInstance;
let errorMock: jest.SpyInstance;
Expand Down Expand Up @@ -114,15 +114,6 @@ test('run-vcpkg: basic run with exception', async () => {
// Act and Assert.
const vcpkg: vcpkgaction.VcpkgAction = new vcpkgaction.VcpkgAction(baseUtil);
await expect(async () => await vcpkg.run()).rejects.toThrowError();

// Run post action.
const vcpkgPostAction = new vcpkgpostaction.VcpkgPostAction(
baseUtil,
false,
baseutil.createKeySet(["primary"]),
['/dummy/Path/'],
"primary");
await vcpkgPostAction.run();
});

test('run-vcpkg: basic run with exception on saving the cache', async () => {
Expand All @@ -132,15 +123,6 @@ test('run-vcpkg: basic run with exception on saving the cache', async () => {
// Act and Assert.
const vcpkg: vcpkgaction.VcpkgAction = new vcpkgaction.VcpkgAction(baseUtil);
await vcpkg.run();

// Run post action.
const vcpkgPostAction = new vcpkgpostaction.VcpkgPostAction(
baseUtil,
false,
baseutil.createKeySet(["primary"]),
['/dummy/Path/'],
null);
await vcpkgPostAction.run();
});

test('run-vcpkg: cache hit', async () => {
Expand All @@ -156,8 +138,6 @@ test('run-vcpkg: cache hit', async () => {
const restoreCacheSpy = jest.spyOn(cache, "restoreCache").mockImplementation(
function (a, b, c): Promise<string> { return Promise.resolve(primaryHitKey); });
process.env.INPUT_VCPKGDIRECTORY = "/var/tmp/vcpkg";
process.env.INPUT_APPENDEDCACHEKEY = "appendedCacheKey";
process.env.INPUT_PREPENDEDCACHEKEY = "prependedCacheKey";

// Act.
const vcpkg: vcpkgaction.VcpkgAction = new vcpkgaction.VcpkgAction(baseUtil);
Expand All @@ -167,14 +147,7 @@ test('run-vcpkg: cache hit', async () => {
expect(restoreCacheSpy).toBeCalledTimes(1);
const key = restoreCacheSpy.mock.calls[0][1];

// Run post action.
const vcpkgPostAction = new vcpkgpostaction.VcpkgPostAction(baseUtil,
false,
keys,
['/dummy/Path/'],
keys.primary);
await vcpkgPostAction.run();
// Cache was hit, and cache.save() must not be called in the post-action.
// Cache was hit, and cache.save() must not be called.
expect(saveCacheSpy).toBeCalledTimes(0);
});

Expand All @@ -193,27 +166,11 @@ test('run-vcpkg: cache miss', async () => {
// Asserts.
expect(restoreCacheSpy).toBeCalledTimes(1);
const key = restoreCacheSpy.mock.calls[0][1];
// Cache was missed, and cache.save() is not going to be called in the action, but it
// will in the post action.
expect(saveCacheSpy).toBeCalledTimes(0);
// The "key cache hit" must be empty as there was no cache hit.
expect(core.getState(vcpkgaction.VCPKG_KEY_CACHE_HIT_STATE)).toBeFalsy();
console.log(core.getState(vcpkgaction.VCPKG_CACHE_COMPUTEDKEY_STATE));
expect(vcpkgRunnerRunSpy).toBeCalledTimes(0);

// Run post action.
// Artificially set the state for VCPKG_CACHE_COMPUTEDKEY_STATE (it would only be set if this
// code is running by an GitHub runner indeed)
process.env.STATE_VCPKG_CACHE_COMPUTEDKEY_STATE = '{"primary":"runnerOS=darwin","restore":[]}';
const vcpkgPostAction = new vcpkgpostaction.VcpkgPostAction(baseUtil,
false,
baseutil.createKeySet([key]),
['/dummy/Path/'],
null);
await vcpkgPostAction.run();
// Cache was missed, and cache.save() is called in the post-action.
// Cache was missed, and cache.save() is going to be called in the action.
expect(saveCacheSpy).toBeCalledTimes(1);
expect(saveCacheSpy.mock.calls[0][1]).toBe(key);
// The "key cache hit" must be empty as there was no cache hit.
expect(vcpkgRunnerRunSpy).toBeCalledTimes(0);
});

test('run-vcpkg: cache must not be restored/saved when "doNotCache" is true', async () => {
Expand Down Expand Up @@ -300,10 +257,9 @@ test('getVcpkgCommitId() tests', async () => {
test('computeCacheKey(): vcpkg not as a submodule (no commit id user provided and no vcpkg.json found)', async () => {
// Arrange.
const expected: baseutil.KeySet = {
"primary": "prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=1234_appendedKey=appendedCacheKey",
"primary": "runnerOS=imageos42-vcpkgGitCommit=1234",
"restore":
[
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=1234"
]
};
process.env.ImageOS = "imageos";
Expand All @@ -318,12 +274,8 @@ test('computeCacheKey(): vcpkg not as a submodule (no commit id user provided an
// Act and Assert.
expect(await vcpkgutils.Utils.computeCacheKeys(
baseUtil,
null,
null,
".",
"",
"appendedCacheKey",
"prependedCacheKey")).toStrictEqual(expected);
"")).toStrictEqual(expected);
expect(warningMock).toBeCalledTimes(0);

// Cleanup.
Expand All @@ -334,11 +286,9 @@ test('computeCacheKey(): vcpkg not as a submodule (no commit id user provided an
test('computeCacheKey(): vcpkg not as a submodule (no commit id user provided)', async () => {
// Arrange.
const expected: baseutil.KeySet = {
"primary": "prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=1234_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json_appendedKey=appendedCacheKey",
"primary": "runnerOS=imageos42-vcpkgGitCommit=1234",
"restore":
[
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=1234_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json",
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=1234"
]
};
process.env.ImageOS = "imageos";
Expand All @@ -350,13 +300,8 @@ test('computeCacheKey(): vcpkg not as a submodule (no commit id user provided)',

// Act and Assert.
expect(await vcpkgutils.Utils.computeCacheKeys(
baseUtil,
"hash-of-vcpkg.json",
"hash-of-vcpkg-configuration.json",
".",
"",
"appendedCacheKey",
"prependedCacheKey")).toStrictEqual(expected);
baseUtil, "", null
)).toStrictEqual(expected);
expect(warningMock).toBeCalledTimes(0);

// Cleanup.
Expand All @@ -366,12 +311,8 @@ test('computeCacheKey(): vcpkg not as a submodule (no commit id user provided)',
test('computeCacheKey(): vcpkg as a submodule (no commit id user provided)', async () => {
// Arrange.
const expected: baseutil.KeySet = {
"primary": "prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=5678_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json_appendedKey=appendedCacheKey",
"restore":
[
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=5678_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json",
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=5678"
]
"primary": "runnerOS=imageos42-vcpkgGitCommit=5678",
"restore": []
};
process.env.ImageOS = "imageos";
process.env.ImageVersion = "42";
Expand All @@ -382,13 +323,7 @@ test('computeCacheKey(): vcpkg as a submodule (no commit id user provided)', asy

// Act and Assert.
expect(await vcpkgutils.Utils.computeCacheKeys(
baseUtil,
"hash-of-vcpkg.json",
"hash-of-vcpkg-configuration.json",
".",
"",
"appendedCacheKey",
"prependedCacheKey")).toStrictEqual(expected);
baseUtil, "", null)).toStrictEqual(expected);
expect(warningMock).toBeCalledTimes(0);

// Cleanup.
Expand All @@ -398,12 +333,8 @@ test('computeCacheKey(): vcpkg as a submodule (no commit id user provided)', asy
test('computeCacheKey(): vcpkg as a submodule, with user provided Git commit id, it must trigger a warning', async () => {
// Arrange.
const expected: baseutil.KeySet = {
"primary": "prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=0912_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json_appendedKey=appendedCacheKey",
"restore":
[
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=0912_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json",
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=0912"
]
"primary": "runnerOS=imageos42-vcpkgGitCommit=0912",
"restore": []
};
process.env.ImageOS = "imageos";
process.env.ImageVersion = "42";
Expand All @@ -414,24 +345,16 @@ test('computeCacheKey(): vcpkg as a submodule, with user provided Git commit id,

// Act and Assert.
expect(await vcpkgutils.Utils.computeCacheKeys(
baseUtil,
"hash-of-vcpkg.json",
"hash-of-vcpkg-configuration.json",
path.resolve("."),
"vcpkgcommitid",
"appendedCacheKey",
"prependedCacheKey")).toStrictEqual(expected);
baseUtil, "", "userProvidedGitCommitId")).toStrictEqual(expected);
expect(warningMock).toBeCalledTimes(1);
vcpkgCommitIdMock.mockClear();
});

test('computeCacheKey(): vcpkg with user provided commit it must not trigger a warning', async () => {
// Arrange.
const expected: baseutil.KeySet = {
"primary": "prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=userId_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json_appendedKey=appendedCacheKey",
"restore": [
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=userId_vcpkgJson=hash-of-vcpkg.json-vcpkgConfigurationJson=hash-of-vcpkg-configuration.json",
"prependedKey=prependedCacheKey-runnerOS=imageos42-vcpkgGitCommit=userId"]
"primary": "runnerOS=imageos42-vcpkgGitCommit=userProvidedCommitId",
"restore": []
};
process.env.ImageOS = "imageos";
process.env.ImageVersion = "42";
Expand All @@ -442,12 +365,6 @@ test('computeCacheKey(): vcpkg with user provided commit it must not trigger a w

// Act and assert.
expect(await vcpkgutils.Utils.computeCacheKeys(
baseUtil,
"hash-of-vcpkg.json",
"hash-of-vcpkg-configuration.json",
"/Users/luca/github/run-vcpkg/__tests__/assets/",
"userId",
"appendedCacheKey",
"prependedCacheKey")).toStrictEqual(expected);
baseUtil, "", "userProvidedCommitId")).toStrictEqual(expected);
expect(warningMock).toBeCalledTimes(0);
});

0 comments on commit ec2db93

Please sign in to comment.