GitHub Actions
GitHub Actions were introduced in 2018 to design CI/CD workflows for GitHub projects. Actions are relatively short and reusable pieces of code that simplify the process of creating a CI/CD workflow.
- GitHub Actions Marketplace (19k+ actions)
 - GitHub Actions Documentation
 - GitHub Actions Quickstart
 - GitHub Awesome Actions (22.7k β)
 - GitHub Workflow Syntax (βͺ)
 
Terminology
- 
Steps βοΈ: a command or an action such as
run tests - 
Jobs ποΈ: a job is an ordered set of steps to achieve a goal. They can be run in parallel or sequentially.
 - 
Workflow π: an automated process made of jobs. For instance, we could have a workflow for building and testing the project.
 
The workflow status is visible next to each commit: 
 (passed).
Basic syntax
Workflows are defined in YAML files stored in .github/workflows/. Their names are based on the YAML file name (e.g., Build for build.yml).
A basic Action executing job_name on every push:
name: Action Name
on: [push]
jobs:
  job_name:
    runs-on: ubuntu-latest
    steps:
    # unnamed command
    - run: echo "Hello, World!"
    # named command
    - name: Saying Hello
      run: echo "Hello, World!"
A runner is an agent executing commands. The runs-on parameter designates which runner to use. You can use GitHub-hosted runners such as ubuntu-latest or windows-latest or use self-hosted runners.
A common action is checkout to clone your repository:
    - name: Check out repository code
      uses: actions/checkout@v3
For each step, you may use these optional attributes:
      - name: XXX
        # only execute based on a condition
        if: runner.os == 'Windows'
        # run multiple commands
        run: |
          xxx
          xxx
        env: # set an environment variable
          XXX: xxx
Advanced syntax
Trigger
The on keyword determines what events can trigger a workflow.
on:
  pull_request:         # on any pull request
on:
  push:                 # push on main
    branches: [ main ]
  pull_request:         # merge request on main
    branches: [ main ]
  schedule:             # automatically
    - cron: '0 3 * * 5'
Strategy
The strategy keyword lets us define variables. The job below will be executed 4 times as we have 4 values (cartesian product of all variables).
    strategy:
      matrix:
        some_variable: [10, 11, 12, 13]
    steps:
      - name: Use Version ${{ matrix.some_variable }}
        run: echo "use version ${{ matrix.some_variable }}"
Some actions
Java actions
actions/setup-java to install and configure Java.
    - name: Set up JDK 16
      uses: actions/setup-java@v2
      with:
        java-version: '16'
        distribution: 'adopt'
    - name: Run gradle tests
      uses: gradle/gradle-build-action@v2
      with:
        arguments: test
β‘οΈ See also: gradle-wrapper-validation.
OCAML actions
ocaml/setup-ocaml to install and configure OCaml.
      - name: Use OCaml 4.13.1
        uses: ocaml/setup-ocaml@v2
        with:
          ocaml-compiler: 4.13.1
Node.js actions
actions/setup-node to install and configure Node.
    - name: Use Node.js 16.16.0
      uses: actions/setup-node@v2
      with:
        node-version: 16.16.0
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test
Cache build
actions/cache to cache build results.
Static code analysis
GitHub/codeql-action for CodeQL static code analysis.
Code quality analysis
JetBrains/qodana-action for Qodana code quality analysis.
Dependabot
Dependabot is a "bot" that checks your dependencies. If it detects that we can upgrade a dependency, it opens a pull-request with the suggested upgrade. Here is the official tutorial π.
It can also detect vulnerabilities in dependencies and notify developers to upgrade their dependencies.
Here are some dependabot.yml examples:
version: 2
updates:
  - package-ecosystem: "gradle"
    directory: "/"
    schedule:
      interval: "daily"
version: 2
updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"
      time: "13:00"
    open-pull-requests-limit: "99"
    versioning-strategy: "increase"
It works by analyzing dependencies in the ecosystem file:
npm: package.jsongradle: build.gradledocker: Dockerfilepip: requirements.txt- ...
 
π» To-do π»
Stuff that I found, but never read/used yet.