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

ci: ensure tests use build output and simplify CI/CD workflow #9649

Merged
merged 4 commits into from
Aug 28, 2024

Conversation

cwillisf
Copy link
Contributor

Thanks, @takaokouji, for making me take a closer look at the caching behavior in this workflow. Subtle and dangerous!

Resolves

Proposed Changes

In the previous version, the build/ directory was cached with this key:

key: ${{ runner.os }}-build-${{ hashFiles('package-lock.json') }}

Later workflow steps would restore the build output with this same key.

The change proposed in this PR combines the steps together, eliminating the need to save and restore caches between steps.

Reason for Changes

As @takaokouji observed in #9643, this means that if a commit or PR doesn't change package-lock.json, the cache key will not change. Two unrelated builds, possibly with very different content in src/ or elsewhere, could share the same build cache. In this case, when the later testing steps of the two builds each restore the cache, they'll both be testing the same build output. One of them won't be testing what you expect!

Luckily, the deploy steps also used the same cache keys, so they also didn't deploy what you expect. I say "luckily" because the alternative is to release something that didn't run any tests.

All the caching and retrieval steps also took a lot of time, enabled only a tiny amount of extra parallelism (in the deploy steps), and added a lot of complexity to the workflow. Removing all of that means a faster, easier-to-understand workflow with no sneaky gremlins making us test or deploy the wrong thing.

Thanks, @takaokouji, for making me take a closer look at the caching
behavior in this workflow. Subtle and dangerous!

In the previous version, the `build/` directory was cached with this
key:
```yaml
key: ${{ runner.os }}-build-${{ hashFiles('package-lock.json') }}
```

As @takaokouji observed, this means that if a commit or PR doesn't
change `package-lock.json`, the cache key will not change. Two unrelated
builds, possibly with very different content in `src/` or elsewhere,
could share the same build cache. In this case, when the later testing
steps restore the cache, they'll both be testing the same build output.
One of them won't be testing what you expect!

Luckily, the deploy steps also used the same cache keys, so they also
didn't deploy what you expect. I say "luckily" because the alternative
is to release something that didn't run any tests.

All the caching and retrieval steps also took a lot of time, enabled
only a tiny amount of extra parallelism (in the deploy steps), and added
a lot of complexity to the workflow. Removing all of that means a
faster, easier-to-understand workflow with no sneaky gremlins making us
test or deploy the wrong thing.
@cwillisf
Copy link
Contributor Author

For my first test, this new workflow took about 10 minutes to run. The previous workflow was more like 20 minutes.

@cwillisf
Copy link
Contributor Author

OK, sorry for the churn. This is genuinely ready now, I think 😅

Commit dea503f was because I realized that the build & test workflow didn't run on this PR, and we do want to test PRs!

Commit 7bb299b was because, once the build & test workflow did run on this PR, I realized that it was attempting to run the deploy steps. That's good for semantic-release since deploying from the "wrong" branch causes a dry run, effectively a config test, but it's bad for the GH Pages deploy since that fails with a permission error.

- run: |
for F in chrome chromium chromedriver; do
which $F && $F --version || echo Not found: $F
done
- name: Run Integration Tests
env:
JEST_JUNIT_OUTPUT_NAME: results.txt
JEST_JUNIT_OUTPUT_DIR: test-results/integration
run: npm run test:integration -- --reporters="default" --reporters="jest-junit"
- name: Store Integration Test Results
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3
with:
name: integration-test-output
path: ./test-results/*
Copy link
Contributor

Choose a reason for hiding this comment

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

With the the env variables as they are the integration tests artifact would contain both unit and integration tests result.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, good point - thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I combined the two steps for storing test results, so now there's one artifact that contains any/all output from both testing steps. I set it to run "always" so that (for example) if the unit tests have output but the build fails, the unit test output is still available. That also means any output from failed tests will be available, which probably should have been the way we set it up to begin with!

@MiroslavDionisiev
Copy link
Contributor

I think it is safe to cache node-modules as if package-lock.json is not updated we would not expect any change there.

@cwillisf
Copy link
Contributor Author

The npm ci command deletes everything in the node_modules directory, so caching that ends up being ineffective. The setup-node action caches the files used by npm ci:
https://github.com/actions/setup-node?tab=readme-ov-file#caching-global-packages-data

@cwillisf cwillisf merged commit 43cd8f2 into scratchfoundation:develop Aug 28, 2024
2 checks passed
@cwillisf cwillisf deleted the test-the-actual-build branch August 28, 2024 20:10
Copy link

🎉 This PR is included in version 4.0.15 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants