#browser-automation
#continuous-integration
#github
## Documentation entry points
- [Introduction to GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/introduction-to-github-actions)
- Documentation for the [_setup-node_](https://github.com/marketplace/actions/setup-node-js-environment) action
- [Setting environment variables](https://docs.github.com/en/actions/reference/environment-variables#about-environment-variables) and [making secrets available](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
- Parallelize/parameterize jobs with [`strategy.matrix`](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix)
- [Actions Cheat Sheet](https://github.github.io/actions-cheat-sheet/actions-cheat-sheet.html)
- [Contexts](https://docs.github.com/en/actions/learn-github-actions/contexts)
## Terminology
From [Introduction to GitHub Actions](https://docs.github.com/en/actions/learn-github-actions/introduction-to-github-actions) in the GitHub Actions documentation:
- An **Event** or schedule triggers a workflow
- „The workflow can be used to build, test, package, release, or deploy a project on GitHub.“
- **Workflow**
- **Job** (multiple can be run in parallel, but also sequentially/conditionally)
- **Step** (is either an action or a shell command; each step in a job executes on the same runner, so they can share data)
- **Action** („actions are the smallest portable building block of a workflow. You can create your own actions, or use actions created by the GitHub community“)
- **Runners** execute jobs. A runner is a server that has the [GitHub Actions Runner application](https://github.com/actions/runner) installed. It listens for available jobs, runs one at a time and reports back the result. Available on GitHub, but can also be self-hosted. The runners are based on Ubuntu, Windows and macOS
- Workflow definitions are stored in **.yml** files located in the **.github/workflows** folder of a repository
- [Types of actions explained](https://docs.github.com/en/actions/creating-actions/about-custom-actions?learn=create_actions&learnProduct=actions) (Docker, JavaScript, Composite)
## Runners
The GitHub Actions runners come with a decent bunch of software installed. Example for an [Ubuntu image](https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md) (note that they also offer Windows and macOS runners):
- Languages/runtimes (e.g. Bash, Node.js)
- Package managers (e.g. Homebrew, [[NPM]], Yarn)
- Tools (e.g. Git, Kubectl, Minikube, NVM)
- Browsers and drivers (Chrome, Chromium, Firefox, Chromedriver, Geckodriver)
- Databases
## Repository for experiments
https://github.com/systemboogie/explore-github-actions
## Pointers for further reading
The whole GitHub Actions documentation reads great and there is a whole universe to discover. At first glance, I found the following topics interesting:
- [Sharing data between jobs](https://docs.github.com/en/actions/learn-github-actions/essential-features-of-github-actions#sharing-data-between-jobs). By using the GitHub CLI (which is available on the runners), it also seems to be possible to download artifacts from other workflows
- [Managing complex workflows](https://docs.github.com/en/actions/learn-github-actions/managing-complex-workflows)
- [Workflow syntax for GitHub Actions](https://docs.github.com/actions/reference/workflow-syntax-for-github-actions#onpushpull_requestpaths)
- [Security hardening](https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions)
## Learnings
### YAML can be hard
Same as in [[CircleCI#YAML can be hard]].
Other than that, the GitHub Actions docs contain a reference to ["Learn YAML in Y minutes"](https://learnxinyminutes.com/docs/yaml/) which is quite useful.
### Not possible to `git push` on protected branch
Doing a release by a workflow on the default branch is [currently not possible if that branch is protected](https://github.community/t/how-to-push-to-protected-branches-in-a-github-action/16101). This because the `GITHUB_TOKEN` available to the workflow does not have the necessary permission (which makes sense). The common **(but not recommended)** workaround is to pass a personal access token to the job that does the push. This is also mentioned [in the semantic-release documentation](https://semantic-release.gitbook.io/semantic-release/recipes/ci-configurations/github-actions#pushing-package.json-changes-to-a-master-branch).
### Behavior of `on` filters
The following example skips a workflow if a push **only** contains changes to a certain folder (_docs_ in this example). If a push contains changes in another folder, the workflow runs, also if the _docs_ folder has changes. [The docs clearly mention that](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-excluding-paths).
```yml
on:
push:
paths-ignore:
- 'docs/**'
```
The following example skips a workflow for a certain path and for all tags. Note that this needs also a `branches` filter which includes all branches. Otherwise, no workflows will run **at all**. The docs mention that [here](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore):
> If you define only `tags`/`tags-ignore` or only `branches`/`branches-ignore`, the workflow won't run for events affecting the undefined Git ref.
... where "undefined Git ref" refers to the missing branch in this case.
```yml
on:
push:
branches:
- '**'
paths-ignore:
- 'docs/**'
tags-ignore:
- '**'
```
### GitHub Actions for making GitHub API requests
#### octokit/request-action
[**octokit/request-action**](https://github.com/octokit/request-action) offers a nice way of interacting with the [[GitHub#GitHub API]]. Some learnings:
- The `GITHUB_TOKEN` provided during workflow runs does not allow certain tasks (which is reasonable)
- Although octokit belongs to GitHub, **octokit/request-action** is not marked as coming from a "verified creator". This means that the Actions permissions in the respective repository need to be relaxed to be able to use the action
- I found it a bit fiddly to properly construct from the [REST API docs](https://docs.github.com/en/rest) what needs to be passed to the actions' `with` field
#### actions/github-script
There is also [**actions/github-script**](https://github.com/actions/github-script), whose API is not that raw as that of **octokit/request-action**.
## Interesting articles
- [Actionlint](https://rhysd.github.io/actionlint/) - a "static checker for GitHub Actions workflow files"
- [GitHub Actions supply chain attacks](https://www.wolfe.id.au/2021/04/26/github-actions-supply-chain-attacks/)
- [What are Github Actions and How Can You Automate Tests and Slack Notifications?](https://www.freecodecamp.org/news/what-are-github-actions-and-how-can-you-automate-tests-and-slack-notifications/)
- [5 simple things every developer can do to ship more secure code](https://github.blog/2022-04-22-5-simple-things-every-developer-can-do-to-ship-more-secure-code/)