Skip to content

Add a setting to specify what to do on hash mismatch and default it to error#461

Merged
danwkennedy merged 3 commits into
mainfrom
danwkennedy/digest-mismatch-behavior
Feb 23, 2026
Merged

Add a setting to specify what to do on hash mismatch and default it to error#461
danwkennedy merged 3 commits into
mainfrom
danwkennedy/digest-mismatch-behavior

Conversation

@danwkennedy
Copy link
Copy Markdown
Contributor

@danwkennedy danwkennedy commented Jan 30, 2026

Description

This'll go in after the unzip PR.

Adds a new digest-mismatch setting to specify what to do if the hashes are mismatched. We're going to default this to error.

Breaking Changes

  • Downloads that fail the hash check will fail now. We believe this is a sensible default to increase security. If this is not acceptable, set the digest-mismatch setting to warn to change it back to the previous behavior.

@danwkennedy danwkennedy requested a review from a team as a code owner January 30, 2026 20:12
Base automatically changed from danwkennedy/download-no-unzip to main February 23, 2026 20:05
@danwkennedy danwkennedy force-pushed the danwkennedy/digest-mismatch-behavior branch from bcacd8b to ccc058e Compare February 23, 2026 20:07
Copilot AI review requested due to automatic review settings February 23, 2026 20:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new digest-mismatch input parameter that allows users to control the behavior when downloaded artifacts fail digest validation. The default behavior is changed from warning to error, making the action more secure by default. This is a breaking change that improves security by failing when artifact integrity cannot be verified.

Changes:

  • Added a new digest-mismatch input with four options: ignore, info, warn, and error (default)
  • Modified digest validation logic to collect all mismatches and handle them according to the configured behavior
  • Added comprehensive test coverage for all four behavior options
  • Updated documentation to explain the breaking change

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/constants.ts Added DigestMismatch input enum and DigestMismatchBehavior enum defining the four behavior options
src/download-artifact.ts Implemented input validation and digest mismatch handling logic with switch statement for different behaviors
dist/index.js Compiled distribution file reflecting the source code changes
action.yml Added digest-mismatch input definition with description and default value of 'error'
tests/download.test.ts Added tests for default error behavior and all three alternative behaviors (warn, info, ignore)
README.md Documented the breaking change and new parameter in the v8 "What's new" section

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +237 to +256
test('errors when digest validation fails (default behavior)', async () => {
const mockArtifact = {
id: 123,
name: 'corrupted-artifact',
size: 1024,
digest: 'abc123'
}

jest
.spyOn(artifact.default, 'getArtifact')
.mockImplementation(() => Promise.resolve({artifact: mockArtifact}))

jest
.spyOn(artifact.default, 'downloadArtifact')
.mockImplementation(() => Promise.resolve({digestMismatch: true}))

await expect(run()).rejects.toThrow(
'Digest validation failed for artifact(s): corrupted-artifact'
)
})
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for invalid digest-mismatch input values. The validation logic in the implementation (lines 37-43 of src/download-artifact.ts) throws an error for invalid values like 'invalid-option', but there's no test verifying this behavior. Consider adding a test case that verifies an error is thrown when an invalid value is provided for the digest-mismatch input.

Copilot uses AI. Check for mistakes.
)
expect(core.info).toHaveBeenCalledWith('Total of 1 artifact(s) downloaded')
})

Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for multiple artifacts with digest mismatches. The implementation collects all artifacts with digest mismatches and reports them together in the error message, but there's no test verifying this behavior when multiple artifacts fail digest validation. Consider adding a test case that downloads multiple artifacts where more than one has a digest mismatch to verify the error message correctly lists all affected artifacts.

Suggested change
test('fails with aggregated message when multiple artifacts have digest mismatches', async () => {
const mockArtifacts = [
{
id: 101,
name: 'corrupted-artifact-1',
size: 2048,
digest: 'hash-1'
},
{
id: 102,
name: 'corrupted-artifact-2',
size: 4096,
digest: 'hash-2'
}
]
// Configure inputs so that digest mismatches cause the action to fail.
// If 'fail' is the default, this keeps behavior explicit without changing it.
mockInputs({
[Inputs.DigestMismatch]: 'fail'
})
jest
.spyOn(artifact.default, 'listArtifacts')
.mockImplementation(() =>
Promise.resolve({
artifacts: mockArtifacts
})
)
jest
.spyOn(artifact.default, 'downloadArtifact')
.mockImplementation(() =>
Promise.resolve({
digestMismatch: true
})
)
await run()
expect(core.setFailed).toHaveBeenCalledTimes(1)
const failureMessage = (core.setFailed as jest.Mock).mock.calls[0][0]
expect(failureMessage).toEqual(
expect.stringContaining('corrupted-artifact-1')
)
expect(failureMessage).toEqual(
expect.stringContaining('corrupted-artifact-2')
)
})

Copilot uses AI. Check for mistakes.
@danwkennedy danwkennedy merged commit 70fc10c into main Feb 23, 2026
12 checks passed
@danwkennedy danwkennedy deleted the danwkennedy/digest-mismatch-behavior branch February 23, 2026 20:27
@danwkennedy danwkennedy restored the danwkennedy/digest-mismatch-behavior branch February 23, 2026 20:41
@danwkennedy danwkennedy deleted the danwkennedy/digest-mismatch-behavior branch February 23, 2026 20:43
mergify Bot added a commit to ArcadeData/arcadedb that referenced this pull request Mar 3, 2026
… ci]

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7.0.0 to 8.0.0.
Release notes

*Sourced from [actions/download-artifact's releases](https://github.com/actions/download-artifact/releases).*

> v8.0.0
> ------
>
> v8 - What's new
> ---------------
>
> ### Direct downloads
>
> To support direct uploads in `actions/upload-artifact`, the action will no longer attempt to unzip all downloaded files. Instead, the action checks the `Content-Type` header ahead of unzipping and skips non-zipped files. Callers wishing to download a zipped file as-is can also set the new `skip-decompress` parameter to `false`.
>
> ### Enforced checks (breaking)
>
> A previous release introduced digest checks on the download. If a download hash didn't match the expected hash from the server, the action would log a warning. Callers can now configure the behavior on mismatch with the `digest-mismatch` parameter. To be secure by default, we are now defaulting the behavior to `error` which will fail the workflow run.
>
> ### ESM
>
> To support new versions of the @actions/\* packages, we've upgraded the package to ESM.
>
> What's Changed
> --------------
>
> * Don't attempt to un-zip non-zipped downloads by [`@​danwkennedy`](https://github.com/danwkennedy) in [actions/download-artifact#460](https://redirect.github.com/actions/download-artifact/pull/460)
> * Add a setting to specify what to do on hash mismatch and default it to `error` by [`@​danwkennedy`](https://github.com/danwkennedy) in [actions/download-artifact#461](https://redirect.github.com/actions/download-artifact/pull/461)
>
> **Full Changelog**: <actions/download-artifact@v7...v8.0.0>


Commits

* [`70fc10c`](actions/download-artifact@70fc10c) Merge pull request [#461](https://redirect.github.com/actions/download-artifact/issues/461) from actions/danwkennedy/digest-mismatch-behavior
* [`f258da9`](actions/download-artifact@f258da9) Add change docs
* [`ccc058e`](actions/download-artifact@ccc058e) Fix linting issues
* [`bd7976b`](actions/download-artifact@bd7976b) Add a setting to specify what to do on hash mismatch and default it to `error`
* [`ac21fcf`](actions/download-artifact@ac21fcf) Merge pull request [#460](https://redirect.github.com/actions/download-artifact/issues/460) from actions/danwkennedy/download-no-unzip
* [`15999bf`](actions/download-artifact@15999bf) Add note about package bumps
* [`974686e`](actions/download-artifact@974686e) Bump the version to `v8` and add release notes
* [`fbe48b1`](actions/download-artifact@fbe48b1) Update test names to make it clearer what they do
* [`96bf374`](actions/download-artifact@96bf374) One more test fix
* [`b8c4819`](actions/download-artifact@b8c4819) Fix skip decompress test
* Additional commits viewable in [compare view](actions/download-artifact@37930b1...70fc10c)
  
[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility\_score?dependency-name=actions/download-artifact&package-manager=github\_actions&previous-version=7.0.0&new-version=8.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants