Fixing code formatting
It is easy to forget to format code before pushing it to GitHub. I usually use husky pre-commit hooks with lint-staged but that requires configuration. It would be so much simpler if continuous integration server could run the formatting task and if there were any changed files, would commit and push them to the source repository, fixing any problems. Turns out, this is pretty (pun intended) simple as the example repo bahmutov/gh-action-with-prettier shows. Here is the .github/workflows/ci.yml file.
The above steps check out the remote source code, install NPM modules (with caching using actions/cache helper), then run Prettier via
npm run format and finally use action mikeal/publish-to-github-action I have found at GitHub Marketplace. This action is super simple - it is a code I usually have written myself to commit local changes and push to remote, see its entrypoint.sh.
The integration of code repository (in this case GitHub) with CI (GitHub Actions) is very convenient from the security point of view. In this case, a secret
GITHUB_TOKEN is automatically injected by the CI - allowing us to easily interact with the remote repository, no extra steps necessary.
Actions are fetched directly from GitHub repositories, not from NPM. Thus you can specify what action to use using a branch name, tag or commit.
I recommend using either latest published branch like:
NPM or Yarn install
~/.npm folder, thus it needs the following boilerplate action.
- name: Cache node modules
actions/cache into cypress-io/github-actions-cache and have refactored the code in branch
reusable-functions to allow using
npm-install action - here is the main logic of the action
If the previously cached
~/.cache/yarn depending on the presence of
yarn.lock folder was successfully restored, then we perform immutable install using
npm ci or
yarn --frozen-lockfile command and are done. If the cache hit was missed, then we need to save the NPM modues folder in action's cache.
Restoring and saving NPM cache folder functions use the forked
cache module and rely on platform and lock file hash to know when a new cache is necessary.
const hasha = require('hasha')
Because the action needs to be ready to go, you need to bundle the action using zeti/ncc for example. Thus the action's
package.json file includes the
dist folder is checked in - because GitHub actions are fetched straight from GitHub source, no from NPM registry. For publishing I use another GitHub action cycjimmy/semantic-release-action that tags and pushes new releases on GitHub and also update
v<major version> branch, like
v1 to always point at the latest release.
You can see this action in ... action at bahmutov/npm-install-action-example/actions. The CI file is simple
bahmutov/[email protected] refers to branch
v1 of the GitHub repository bahmutov/npm-install where the latest semantic release is pushed. On the first build, the cache is empty, and
npm ci has to fetch NPM modules from the registry. Then the folder
~/.npm is cached.
On the second build, the cache is hit, and
npm ci is faster - because it uses only modules from the restored
~/.npm folder, and then skips saving unchanged cache folder.
Finally, I have written cypress-io/github-action to make running Cypress tests on GitHub super simple. Here is how to run tests on a single Linux machine
name: End-to-end tests
Here is more complicated case: running tests in parallel in load balancing mode
name: Parallel Cypress Tests
Super simple and even works across Windows, Mac and Linux machines on CI, see Cypress GitHub Action examples.