Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(agd): rely on checksums, not timestamps #8715

Merged
merged 4 commits into from
Feb 6, 2024
Merged

Conversation

michaelfig
Copy link
Member

@michaelfig michaelfig commented Jan 7, 2024

refs: #8136

Description

Don't use timestamps to track the build dependencies in the bin/agd script and restore-node/action.yml... they get confused because Git doesn't preserve the timestamps. Instead, use sha1sum to generate simple manifests of the dependencies matched to their hashes, and compare those manifests to decide if something needs rebuilding.

This solves a longstanding problem with the #endo-branch: PR feature... it would fail during cosmic-swingset tests since those would be fooled into rerunning the yarn install but without the Endo-overriding packages. With the new manifest-based builds, bin/agd is much more robust.

Security Considerations

Scaling Considerations

Documentation Considerations

Testing Considerations

Upgrade Considerations

@michaelfig michaelfig marked this pull request as ready for review January 7, 2024 23:39
@michaelfig michaelfig self-assigned this Jan 7, 2024
@erights
Copy link
Member

erights commented Jan 29, 2024

@michaelfig , this seems like it would be a big help immediately, seems done, small, and thus possibly quickly reviewable by those with the relevant knowledge. Could you move this forward? Thanks.

@michaelfig
Copy link
Member Author

I pinged y'all as reviewers because it's both CI and shell scripting. Feel free to review or ignore as you feel most comfortable.

@michaelfig michaelfig added the force:integration Force integration tests to run on PR label Feb 5, 2024
Copy link
Member

@kriskowal kriskowal left a comment

Choose a reason for hiding this comment

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

Thank you!

fi
echo "sha=$sha" >> $GITHUB_OUTPUT
cd "${{ inputs.path }}"
Copy link
Member

Choose a reason for hiding this comment

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

What is this notation? Is this mustache interpolation?

Copy link
Member Author

@michaelfig michaelfig Feb 5, 2024

Choose a reason for hiding this comment

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

Yup, or something like moustache.

yarn install

if cmp -s package.json.orig package.json; then
Copy link
Member

Choose a reason for hiding this comment

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

TIL cmp

yarn install

if cmp -s package.json.orig package.json; then
Copy link
Member

Choose a reason for hiding this comment

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

Could also avoid the temporary file: <(git cat-file blob HEAD:package.json)

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice!

Comment on lines +151 to +161
while IFS= read -r line; do
files+=( "$line" )
done < <(yarn -s workspaces info |
sed -ne '/"location":/{ s/.*": "//; s!",.*!/package.json!; p; }')
Copy link
Member

Choose a reason for hiding this comment

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

This might be read more clearly with information piping strictly left to right

Suggested change
while IFS= read -r line; do
files+=( "$line" )
done < <(yarn -s workspaces info |
sed -ne '/"location":/{ s/.*": "//; s!",.*!/package.json!; p; }')
yarn -s workspaces info |
sed -ne '/"location":/{ s/.*": "//; s!",.*!/package.json!; p; }' |
while IFS= read -r line; do
files+=( "$line" )
done

Is there no other idiom to self-concat the bash array? while subshells for every iteration. I don’t expect that’s a problem, but I have a blind spot for bash arrays.

Copy link
Member

Choose a reason for hiding this comment

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

Did some fiddling locally and it seems that this should work:

file+=( $(
  yarn -s workspaces info |
  sed -ne '/"location":/{ s/.*": "//; s!",.*!/package.json!; p; }'
) )

That said, I’m weary of bash arrays because it’s hard to predict when they’re going to compose poorly with the command line length limit. File variable concatenation would look like:

FILES=$(git hash-object -w /dev/null)
FILES=$( git hash-object -w <(
  git cat-file blob "$FILES"
  yarn -s workspaces info |
  sed -ne '/"location":/{ s/.*": "//; s!",.*!/package.json!; p; }'
))

Copy link
Member Author

Choose a reason for hiding this comment

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

while subshells for every iteration

That is surprising to me. Even when read is a builtin that has to set a variable in its caller?

Copy link
Member Author

Choose a reason for hiding this comment

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

I use a bash array because I don't trust the escaping (or lack thereof) of other subcommands. I'd like this script to match bin/agd, which doesn't currently require Git.

Copy link
Member

@kriskowal kriskowal Feb 5, 2024

Choose a reason for hiding this comment

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

I’ve had trouble with while accumulators in the past. Yeah, verified:

numbers=( 0 )
seq 10 | while read -r number; do
  numbers+=( $numbers "$number" )
done
echo "${numbers[*]}"
# 0

Copy link
Member Author

Choose a reason for hiding this comment

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

It's the pipe that starts the subprocess, not the while:

numbers=( 0 )
while read -r number; do
  numbers+="$numbers $number";
done < <(seq 10)
echo "${numbers[*]}"

results in:

00 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 700 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 7 800 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 700 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 7 8 900 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 700 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 7 800 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 700 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 600 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 500 100 1 200 100 1 2 300 100 1 200 100 1 2 3 400 100 1 200 100 1 2 300 100 1 200 100 1 2 3 4 5 6 7 8 9 10

Copy link
Member

Choose a reason for hiding this comment

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

Ahah! Thank you. That makes sense and rationalizes the right to left flow!

@@ -64,12 +64,16 @@ publish() {
yarn build
git commit --allow-empty -am "chore: prepare for publishing"

yarn lerna run build:types
Copy link
Member

Choose a reason for hiding this comment

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

In the sync, I fixed this in one place but not here. In the future, grepping for build:types and clean:types should be sufficient to be sure we update everywhere it’s needed, but I wonder if there’s anywhere we can leave a note for our future selves where we’d be likely to find it when we needed it. I don’t have a suggestion.

yarn install

if cmp -s package.json.orig package.json; then
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you want

Suggested change
if cmp -s package.json.orig package.json; then
if ! cmp -s package.json.orig package.json; then

Otherwise add the comment "if package.json is unchanged...".

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. Good catch!

@michaelfig michaelfig force-pushed the mfig-build-uses-hashes branch 2 times, most recently from 7f4d14c to dc5f21e Compare February 6, 2024 01:29
bin/agd Outdated
if test "${1-''}" = build; then
NO_BUILD=false
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to normalize this to true in the "else" case? I see below that the value of the variable is being executed as a command to terminate a pipeline with the desired status.

Copy link
Member Author

Choose a reason for hiding this comment

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

While I don't want to force it to true, it does make sense to normalize it to an executable boolean (one of true or false). Thanks for the suggestion!

@michaelfig michaelfig dismissed JimLarson’s stale review February 6, 2024 15:54

JimLarson approved the PR; he probably just forgot to dismiss this request for changes.

@michaelfig michaelfig added the automerge:no-update (expert!) Automatically merge without updates label Feb 6, 2024
@mergify mergify bot merged commit 386cc49 into master Feb 6, 2024
63 of 64 checks passed
@mergify mergify bot deleted the mfig-build-uses-hashes branch February 6, 2024 20:18
mhofman pushed a commit that referenced this pull request Feb 18, 2024
build(agd): rely on checksums, not timestamps
mhofman pushed a commit that referenced this pull request Feb 18, 2024
build(agd): rely on checksums, not timestamps
mhofman pushed a commit that referenced this pull request Feb 19, 2024
build(agd): rely on checksums, not timestamps
@mhofman mhofman mentioned this pull request Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:no-update (expert!) Automatically merge without updates force:integration Force integration tests to run on PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants