on:
push:
pull_request:
schedule:
# Runs at 5:30 AM UTC every day
- cron: '30 5 * * *'
workflow_dispatch: # for manual dispatch12 GitHub Actions
Acknowledgments
Gemini was used for summarization and generation of sample scripts.
Introduction to GitHub Actions
Automation is needed to facilitate the CI/CD software delivery process, from code commit to deployment.
- Continuous Integration (CI): Frequently merging all developers’ working copies to a shared main branch
- Continuous Delivery (CD): Software engineering approach in which teams produce software in very short cycles
- Software can be reliably released at any time
GitHub Actions is one tool that provides this automation.
GitHub Actions
A CI/CD platform built directly into GitHub.
Allows you to automate, customize, and execute software development workflows right in your repository.
Can be triggered by GitHub events (e.g.
push,pull_request,issue_created)
Why use GitHub Actions?
Integration: Deeply integrated with the GitHub ecosystem
Automation: Automate repetitive tasks like testing, building, and deploying
Visibility: Workflows and their status are visible to the entire team within the repository
Ease of Use: Marketplace of pre-built actions for almost any task
Workflows
Defined in a YAML (
.yml) file in the.github/workflows/directory of your repository.A single repository can have multiple workflows.
Events
- Events are triggers that cause a workflow to run
Jobs
A set of steps that execute on the same runner
Jobs run in parallel by default, but you can define dependencies using the
needskeyword
jobs:
job-name:
runs-on: ubuntu-latest
steps: ...Steps
- Individual tasks within a job
- Can be a shell command (
run:) or a reusable action (uses:) - Executed sequentially within a job
Step Actions
- Reusable units of code to perform a specific task
- Can be from the GitHub Marketplace, a Docker container, or a repository
- Examples:
actions/checkout@v4to check out your repository’s codequarto-dev/quarto-action@v2to render quarto documentationdawidd6/action-send-mail@v3to send an email notification
Runners
- The server where the workflow runs
- GitHub-hosted: Virtual machines provided by GitHub with common software pre-installed (e.g.
ubuntu-latest,windows-latest) - Self-hosted: Your own server, giving you full control over the environment
- GitHub-hosted: Virtual machines provided by GitHub with common software pre-installed (e.g.
Building a Basic Workflow
Initialization
- Option 1: GitHub
- Open the Actions tab of your repository
- Pick a workflow template
- Option 2: Local
- Create a yaml file in your repository at
.github/workflows/(e.g.build.yml)
- Create a yaml file in your repository at
Write / Edit yaml file
Add/edit the
nameandontriggerAdd a
jobssection with a job name (e.g.,build).Under your job name, specify the runner (e.g.
runs-on: ubuntu-latest)
- Add/edit
steps:for each job
name: Hello World
on: [push]
jobs:
hello:
runs-on: ubuntu-latest
steps:
- name: Say Hello
uses: actions/checkout@v4
run: echo "Hello, world! This is my first GitHub Action." Advanced Concepts
Managing Secrets
Sensitive information (API keys, passwords) should never be in your workflow file (or anywhere else in your code)
Store them in the repository’s
Settings > Secrets and variables > ActionsAccess them in your workflow with
${{secrets.SECRET_NAME}}
Job Dependencies
- Use the
needskeyword to ensure jobs run in a specific order
jobs:
build:
runs-on: ubuntu-latest
...
deploy:
needs: build
runs-on: ubuntu-lates
...Caching
- Use
actions/cacheto save dependencies and build outputs between workflow runs - Significantly speeds up workflows by not re-downloading packages like python packages
Reusable workflows
- For teams with multiple repositories, create a single, centralized workflow
- Other repositories can then call this workflow, reducing code duplication and ensuring consistency.
Matrix Builds
- Run a single job across multiple configurations
- Different operating systems
- Language versions
# example courtesy of Gemini
name: CI Multi-OS Test
on: [push, pull_request]
jobs:
test:
# Use a matrix strategy to test on multiple operating systems
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
# Use a setup action for a language (e.g., Node.js)
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm testAdditional examples
Docker image
# Template code provided on GitHub by Docker
name: Docker Image CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build the Docker image
run: docker build . --file Dockerfile --tag my-image-name:$(date +%s)Create and test python app
# Template provided on GitHub by GitHub Actions team
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Python application
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytestDeploy Node.js to Azure Web App
# Template provided on GitHub by Microsoft Azure
# This workflow will build and push a node.js application to an Azure Web App when a commit is pushed to your default branch.
#
# This workflow assumes you have already created the target Azure App Service web app.
# For instructions see https://docs.microsoft.com/en-us/azure/app-service/quickstart-nodejs?tabs=linux&pivots=development-environment-cli
#
# To configure this workflow:
#
# 1. Download the Publish Profile for your Azure Web App. You can download this file from the Overview page of your Web App in the Azure Portal.
# For more information: https://docs.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel#generate-deployment-credentials
#
# 2. Create a secret in your repository named AZURE_WEBAPP_PUBLISH_PROFILE, paste the publish profile contents as the value of the secret.
# For instructions on obtaining the publish profile see: https://docs.microsoft.com/azure/app-service/deploy-github-actions#configure-the-github-secret
#
# 3. Change the value for the AZURE_WEBAPP_NAME. Optionally, change the AZURE_WEBAPP_PACKAGE_PATH and NODE_VERSION environment variables below.
#
# For more information on GitHub Actions for Azure: https://github.com/Azure/Actions
# For more information on the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
# For more samples to get started with GitHub Action workflows to deploy to Azure: https://github.com/Azure/actions-workflow-samples
on:
push:
branches: [ "main" ]
workflow_dispatch:
env:
AZURE_WEBAPP_NAME: your-app-name # set this to your application's name
AZURE_WEBAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
NODE_VERSION: '20.x' # set this to the node version to use
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: npm install, build, and test
run: |
npm install
npm run build --if-present
npm run test --if-present
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v4
with:
name: node-app
path: .
deploy:
permissions:
contents: none
runs-on: ubuntu-latest
needs: build
environment:
name: 'Development'
url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v4
with:
name: node-app
- name: 'Deploy to Azure WebApp'
id: deploy-to-webapp
uses: azure/webapps-deploy@v2
with:
app-name: ${{ env.AZURE_WEBAPP_NAME }}
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}