Github Actions
#
IntroductionAutomation is key for streamlining the work processes, and GitHub Actions are the best way to supercharge the workflow.
GitHub actions is a tool within GitHub that enables continuous integration and a wide range of automation. It supports the three major operating systems, Windows, MacOS and Linux, and any programming language supported by those can be ran. Apart from being triggered by pull requests and commits, actions allows to respond to any GitHub event. It allows to trigger certain GitHub Actions workflow (including open source actions) based on:
- the creation of issues
- comments
- the joining of a new member to the repository
- changes to the GitHub project board
#
Prerequisites- Github account
- Github repository
#
Pricing model- Free for public repositories
- For private repositories pay as you go per minute model applies
#
Types- Community-powered workflows : created, tested and published by GitHub’s large community at the marketplace
- Custom actions
#
Location.github/workflows
directory
#
Syntax and rulesExtension :
.yml
or.yaml
Contains at least one job
Each job contains a set of steps that perform individual tasks
Steps can run commands or use an action. learn more
Example
a worflow starts with a name
name: main-worklfow
Use the on field to define the events that will trigger the worflow
on: push: branches:
- master
pull_request: branches:
- master
A workflow is composed of independent jobs. run-tests will run the application's unit tests
jobs: run-tests:
# Every job requires an operating system to run on. Here, Ubuntu will used runs-on: ubuntu-latest# Jobs contain a list of steps, which are executed consecutively. # Often, the first step is to clone the repository to use the source code it contains. # This will be done by using an action provided by Github, called actions/checkoutsteps: - name: Check out source code uses: actions/checkout@v1 # In this step, run field will be used to execute a command to install pytest and run tests - name: Test with pytest run: | pip install pytest pytest tests.py
#
Environment variables- Case sensitive
- GitHub reserves the
GITHUB_
environment variable prefix for internal use by GitHub. Setting an environment variable or secret with theGITHUB_
prefix will result in an error - Use
_PATH
suffix to point to a filesystem location except forHOME
andGITHUB_WORKSPACE
default variables
#
Default environment variablesGitHub sets default environment variables that are available to every step in a workflow run
steps:
- name: Hello run: echo Hello ${{ secrets.GITHUB_ACTOR }}
#
Custom environment variablesHardcoded, not recommended !
steps:
- name: Hello run: echo Hello $FIRST_NAME $Last_Name env: FIRST_NAME: Abdelkerim Last_Name: Lemaadi
Using secrets
steps:
- name: Hello run: echo Hello ${{ secrets.FIRST_NAME }} ${{ secrets.LAST_NAME }}
#
Authenticating with the GITHUB_TOKEN secret- Use the
GITHUB_TOKEN
secret which is automatically created by GitHub, or - Create a personal access token to perform an action that requires permissions that are not available in the GITHUB_TOKEN
#
Persistence of workflow data through artifactsjob_1: name: job_1 demonstrates the print of a String runs-on: ubuntu-latest steps: - shell: bash run: | echo "Hello" > string-print.txt - name: Upload stdout result for job 1 uses: actions/upload-artifact@v1 with: name: stringPrint path: string-print.txt
job_2: name: job_2 demonstrates the print of another String value needs: job_1 runs-on: windows-latest steps: - name: Download data from job_1 uses: actions/download-artifact@v1 with: name: stringPrint - shell: bash run: | value=`cat stringPrint/string-print.txt` echo $value "World!" > stringPrint/string-print.txt - name: Upload string result for Job2 uses: actions/upload-artifact@v1 with: name: stringPrint path: stringPrint/string-print.txtjob_3: name: Display output needs: job_2 runs-on: macOS-latest steps: - name: Download output uses: actions/download-artifact@v1 with: name: stringPrint
#
Caching dependencies and build outputs- name: Set up Python 3.7 uses: actions/setup-python@v1 with: python-version: 3.7- name: Install pipenv and libpq run: | sudo apt-get install libpq-dev -y pip install pipenv- name: Cache pipenv virtualenv id: cache-pipenv uses: actions/cache@v1 with: path: ~/.local/share/virtualenvs key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }} restore-keys: | ${{ runner.os }}-pipenv- ${{ runner.os }}-- name: Install dependencies if: steps.cache-pipenv.outputs.cache-hit != 'true' run: pipenv install
#
Matrix buildsBuilding software on more than one supported version of a language, operating system or tool
jobs:
test:
name: Test on node ${{ matrix.node_version }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy: matrix:
python_version: [2.7, 3.5, 3.6, 3.7, 3.8] os: [ubuntu-latest, windows-latest, macos-latest]steps: - uses: actions/checkout@v1 - name: Set up Python ${{ matrix.python_version }} uses: actions/setup-python@v2 with: python_version: ${{ matrix.python_version }}
A matrix build can generate at most 256 jobs per workflow run.
#
Runners- Github servers
- self hosted runners
## Build on an integrated package and container registry
Free for public repositories, see more
Publish and consume packages from GitHub Package Registry or any other registry
Docker example
$ docker login docker.pkg.github.com --username username $ docker tag app docker.pkg.github.com/username/repo/app:1.0 $ docker push docker.pkg.github.com/username/repo/app:1.0.0
#
Linting code#
Using Flake8 - name: Lint with flake8 run: | pip install flake8 flake8 .
#
Using pre-commit- With custom invocations
- uses: pre-commit/[email protected] with: extra_args: flake8 --all-files
- In private repositories
- uses: pre-commit/[email protected] with: token: ${{ secrets.GITHUB_TOKEN }}
#
Testing code- name: Test with pytest run: | pip install pytest pytest tests.py
#
Live logs- Always use significant words for jobs's and steps's name (compile, build, test, deploy, release, ...)
- Include emojis
#
Some useful actions- Code coverage
- Build docker images from cache
- Lint code with pre-commit
- Dependencies cache
- Slack