actions / cache

Cache dependencies and build outputs in GitHub Actions
MIT License
4.49k stars 1.2k forks source link

Fix `fail-on-cache-miss` not working #1327

Closed cdce8p closed 6 months ago

cdce8p commented 7 months ago

Description

process.exit overwrites the exit code set by core.setFailed, e.g. the workflow would continue even though fail-on-cache-miss is set and no cache is found.

Originally introduced in

/CC @kgrzebien

Motivation and Context

Fixes #1265

How Has This Been Tested?

Created a workflow which should restore a non-existing cache. With v4.0.0 the workflow continues, with this PR it fails as expected (with fail-on-cache-miss set).

Screenshots (if appropriate):

Types of changes

Checklist:

cdce8p commented 7 months ago

/CC @bethanyj28 Would you mind taking a look at this one? It fixes a bug which was just recently introduced.

bethanyj28 commented 7 months ago

@cdce8p - thanks for the contribution! This seems reasonable to me. Could you add a test case in https://github.com/actions/cache/blob/main/__tests__/restoreImpl.test.ts to validate? Thank you!

cdce8p commented 7 months ago

This seems reasonable to me. Could you add a test case in https://github.com/actions/cache/blob/main/__tests__/restoreImpl.test.ts to validate? Thank you!

I thought about that but I'm not really sure how to do it. The only thing not tested is process.exit(1); however from what I've read online it's difficult to test that with jest. Tbh I wouldn't consider myself an expert in that area. If you've any pointers for me that would be appreciated.

I already looked at #1217 which first introduced the process.exit but AFAICT it didn't add any tests either.

bethanyj28 commented 6 months ago

👋🏻 @cdce8p - sorry for the delay! While the initial change might've not had tests, it would be really nice to validate in the future that we don't regress here. I believe mocking process.exit isn't too bad in jest. Could you do something like this?

test("restore failure with earlyExit should call process exit", async () => {
    // mock `process.exit`
    const processExitMock = jest.spyOn(process, "exit").mockImplementation();

    // simulate a failure
    testUtils.setInput(Inputs.Path, "node_modules");
    const failedMock = jest.spyOn(core, "setFailed");
    const restoreCacheMock = jest.spyOn(cache, "restoreCache");

    // set true for `earlyExit`
    await restoreImpl(new StateProvider(), true);
    expect(restoreCacheMock).toHaveBeenCalledTimes(0);
    expect(failedMock).toHaveBeenCalledWith(
        "Input required and not supplied: key"
    );

    // validate `process.exit` called
    expect(processExitMock).toHaveBeenCalledWith(1);
});

Thank you!

cdce8p commented 6 months ago

@bethanyj28 Would you mind tagging the 4.0.2 release? It would be awesome if this bug would finally be fixed. I already updated the version in package.json and the changelog in this PR.

bethanyj28 commented 6 months ago

Definitely! I appreciate you updating the version 🙏🏻

Emmanuelruina commented 2 months ago

CACHING ACTION