Skip to content

Commit

Permalink
Make ghasum update preserve existing checksums
Browse files Browse the repository at this point in the history
Update the implementation of the `ghasum update` command to preserve
existing sums even if they're invalid. Here, "existing sums" refers to
entries in the sumfile for which the whole ID matches before and after
the update. This helps avoid a scenario where an update silently hides
that an existing dependent action actually changed while it should not
have.

The specification text has been updated accordingly.

The implementation for this is straightforward, but naive and arguably
unnecessarily inefficient. Rather than not computing the checksums, the
approach taken overrides the old values into the list of new checksums.
The motivation for this is primarily simplicity and this choice may be
revisited with a full refactor to reduce unnecessary use of resources
now-used to compute checksums that end up discarded.

A note on the discarded error from the `decode` call: if an error would
occur it already occurs in the call to `version`, hence we don't handle
it twice.
  • Loading branch information
ericcornelissen committed Jul 31, 2024
1 parent 4f1fdb2 commit a3b2e42
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 5 deletions.
13 changes: 8 additions & 5 deletions SPECIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@ by another process leading to an inconsistent state).
If the file lock is obtained, the process shall first read it and parse it
completely to extract the sumfile version. If this fails the process shall exit
immediately unless the `-force` flag is used (see details below). Else it shall
recompute checksums for all actions used in the repository (see [Computing
Checksums]) using the best available hashing algorithm. It shall then store them
in a sumfile (see [Storing Checksums]) using the same sumfile version as before
and releases the lock. As a consequence, this adds missing and removes redundant
checksums from the sumfile.
compute checksums for all new actions used in the repository (see [Computing
Checksums]) using the best available hashing algorithm. Here, a new action also
includes a new version of a previously used action. Additionally, it should
remove any entry which is no longer in use. No existing checksum for a used
action shall be updated unless the `-force` flag is used. It shall then store
them in a sumfile (see [Storing Checksums]) using the same sumfile version as
before and releases the lock. In short, updating will only add new and remove
old checksums from an existing sumfile.

With the `-force` flag the process will ignore errors in the sumfile and fix
those while updating. If the sumfile version can still be determined from
Expand Down
11 changes: 11 additions & 0 deletions internal/ghasum/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"errors"
"io"
"io/fs"
"slices"

"github.com/ericcornelissen/ghasum/internal/cache"
"github.com/ericcornelissen/ghasum/internal/checksum"
Expand Down Expand Up @@ -123,6 +124,7 @@ func Update(cfg *Config, force bool) error {
}

version, err := version(raw)
oldChecksums, _ := decode(raw)
if err != nil {
if !force {
return errors.Join(ErrSumfileRead, err)
Expand All @@ -143,6 +145,15 @@ func Update(cfg *Config, force bool) error {
return err
}

for i, entry := range checksums {
for _, oldEntry := range oldChecksums {
if slices.Equal(entry.ID, oldEntry.ID) {
checksums[i] = oldEntry
break
}
}
}

encoded, err := encode(version, checksums)
if err != nil {
return err
Expand Down
73 changes: 73 additions & 0 deletions testdata/update/success.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,34 @@ stdout 'Ok'
! stderr .
cmp changed/.github/workflows/gha.sum want/gha.sum

# Removal necessary
! cmp remove/.github/workflows/gha.sum want/gha.sum

exec ghasum update -cache .cache/ remove/
stdout 'Ok'
! stderr .
cmp remove/.github/workflows/gha.sum want/gha.sum

# Preserve existing values
! cmp preserve/.github/workflows/gha.sum want/gha-preserve.sum

exec ghasum update -cache .cache/ preserve/
stdout 'Ok'
! stderr .
cmp preserve/.github/workflows/gha.sum want/gha-preserve.sum

-- want/gha.sum --
version 1

actions/checkout@v4.1.1 KsR9XQGH7ydTl01vlD8pIZrXhkzXyjcnzhmP+/KaJZI=
actions/setup-go@v5.0.0 7lPZupz84sSI3T+PiaMr/ML3XPqJaEo7dMaPsQUnM6c=
golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI=
-- want/gha-preserve.sum --
version 1

actions/checkout@v4.1.1 this-is-invalid-but-should-not-be-updated
actions/setup-go@v5.0.0 7lPZupz84sSI3T+PiaMr/ML3XPqJaEo7dMaPsQUnM6c=
golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI=
-- unchanged/.github/workflows/gha.sum --
version 1

Expand Down Expand Up @@ -55,6 +77,57 @@ golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlC
name: Example workflow
on: [push]

jobs:
example:
name: example
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4.1.1
- name: Install Go
uses: actions/setup-go@v5.0.0
with:
go-version-file: go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@3a91952
- name: This step does not use an action
run: Echo 'hello world!'
-- remove/.github/workflows/gha.sum --
version 1

actions/checkout@main PKruFKnotZi8RQ196H3R7c5bgw9+mfI7BN/h0A7XiV8=
actions/checkout@v4.1.1 KsR9XQGH7ydTl01vlD8pIZrXhkzXyjcnzhmP+/KaJZI=
actions/setup-go@v5.0.0 7lPZupz84sSI3T+PiaMr/ML3XPqJaEo7dMaPsQUnM6c=
golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI=
-- remove/.github/workflows/workflow.yml --
name: Example workflow
on: [push]

jobs:
example:
name: example
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4.1.1
- name: Install Go
uses: actions/setup-go@v5.0.0
with:
go-version-file: go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@3a91952
- name: This step does not use an action
run: Echo 'hello world!'
-- preserve/.github/workflows/gha.sum --
version 1

actions/checkout@v4.1.1 this-is-invalid-but-should-not-be-updated
actions/setup-go@v4.1.0 RQ197c5MRKiujfm0VpQ19p7BN/07XFW9H3R7GH36RXi=
golangci/golangci-lint-action@3a91952 CVRgC7gGqkOiujfm0VMRKppg/Ztv8FW9GYmyJzcwlCI=
-- preserve/.github/workflows/workflow.yml --
name: Example workflow
on: [push]

jobs:
example:
name: example
Expand Down

0 comments on commit a3b2e42

Please sign in to comment.