GitHub Actions: Automated Testing For Your App
In today's fast-paced software development world, automation is key to ensuring code quality, consistency, and efficiency. One of the most powerful tools for achieving this is GitHub Actions. GitHub Actions allows you, guys, to automate your software development workflows right in your GitHub repository. From building and testing your code to deploying it to various environments, GitHub Actions can handle it all. In this article, we'll dive into how you can leverage GitHub Actions to set up automated testing for your application, focusing on specific scenarios such as running full builds on main
and tagged releases, performing testing and linting only for pull requests, and building other changesets on request. So, let's make it simple and clear how to set up GitHub Actions for your testing needs.
Before we jump into the specifics, let's take a moment to understand what GitHub Actions is and how it works. At its core, GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. Think of it as a series of automated tasks that run in response to events in your GitHub repository. These events can range from pushing code to opening a pull request or even scheduling tasks to run at specific times.
The basic building blocks of GitHub Actions are workflows, jobs, and steps.
- Workflows: These are the automated processes you define, which can include building, testing, and deploying your application. Workflows are defined in YAML files and stored in the
.github/workflows
directory in your repository. - Jobs: A workflow consists of one or more jobs, which are sets of steps that run on the same runner. Jobs can run sequentially or in parallel, depending on your configuration.
- Steps: Each job consists of one or more steps, which are individual tasks that can execute commands, run scripts, or use pre-built actions. Actions are reusable units of code that you can use to perform common tasks, such as checking out code, setting up a programming language environment, or running tests.
The beauty of GitHub Actions lies in its flexibility and extensibility. You can create custom actions or use actions created by the GitHub community. This makes it easy to integrate with various tools and services, tailoring your workflows to your specific needs. For our context, we’re focusing on using GitHub Actions to automate the testing process, ensuring that our code is always in tip-top shape.
Now that we have a basic understanding of GitHub Actions, let's explore how to set up workflows for the specific scenarios outlined in the introduction. We want to ensure that:
- Full builds occur only on
main
and tagged releases. - Testing and linting occur only for pull requests.
- Other changesets are built only on request.
To achieve this, we'll create multiple workflow files, each targeting different events and branches.
1. Full Build Workflow (main and tagged releases)
First, let's create a workflow that triggers a full build when code is pushed to the main
branch or when a new tag is created. This is crucial for ensuring that your production-ready code is thoroughly tested and built.
Create a new file named full_build.yml
in the .github/workflows
directory of your repository. Here’s an example of what this file might look like:
name: Full Build
on:
push:
branches:
- main
create:
tags: - '*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run build
run: npm run build
- name: Run tests
run: npm run test
Let’s break down this workflow:
name: Full Build
: This line gives our workflow a name, which will be displayed in the GitHub Actions interface.on:
: This section defines the events that trigger the workflow.push
: Triggers the workflow when code is pushed.branches
: Specifies that the workflow should only run when code is pushed to themain
branch.
create
: Triggers the workflow when a new branch or tag is created.tags
: Specifies that workflow only run when a new tag is created.
jobs:
: This section defines the jobs that will run.build
: This is the name of our job.runs-on: ubuntu-latest
: Specifies that the job should run on an Ubuntu virtual machine.steps:
: This section defines the steps that will run within the job.name: Checkout code
: Gives the step a name.uses: actions/checkout@v3
: Uses thecheckout
action to clone the repository to the runner.name: Set up Node.js
:uses: actions/setup-node@v3
: Uses thesetup-node
action to set up a Node.js environment.with:
: Provides input parameters to the action.node-version: '16'
: Specifies the Node.js version to use.
name: Install dependencies
:run: npm install
: Runs thenpm install
command to install project dependencies.name: Run build
:run: npm run build
: Runs the build script defined inpackage.json
.name: Run tests
:run: npm run test
: Runs the test script defined inpackage.json
.
This workflow ensures that every time you push code to the main
branch or create a new tag, a full build is performed, and tests are run. This helps to catch any issues early in the development process.
2. Testing and Linting Workflow (Pull Requests)
Next, let's create a workflow that focuses on testing and linting code only when a pull request is opened or updated. This is essential for maintaining code quality and preventing issues from being merged into the main branch.
Create a new file named pull_request_checks.yml
in the .github/workflows
directory. Here’s an example:
name: Pull Request Checks
on:
pull_request:
branches:
- main
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
Here’s a breakdown of this workflow:
name: Pull Request Checks
: Names the workflow.on:
: Defines the events that trigger the workflow.pull_request
: Triggers the workflow when a pull request is opened, reopened, or updated.branches
: Specifies that the workflow should only run for pull requests targeting themain
branch.
jobs:
: Defines the jobs to run.lint-and-test
: The name of our job.runs-on: ubuntu-latest
: Specifies the runner.steps:
: Defines the steps within the job.name: Checkout code
:uses: actions/checkout@v3
: Checks out the code.name: Set up Node.js
:uses: actions/setup-node@v3
: Sets up Node.js.with:
:node-version: '16'
: Specifies the Node.js version.
name: Install dependencies
:run: npm install
: Installs dependencies.name: Run linter
:run: npm run lint
: Runs the linter (assuming you have alint
script in yourpackage.json
).name: Run tests
:run: npm test
: Runs tests.
This workflow ensures that every pull request targeting the main
branch is linted and tested, providing immediate feedback to developers and helping to maintain code quality.
3. On-Request Build Workflow (Other Changesets)
Finally, let’s create a workflow that allows you to build other changesets on request. This can be useful for testing specific branches or commits without triggering a full build every time code is pushed.
For this scenario, we can use the workflow_dispatch
event, which allows you to manually trigger a workflow from the GitHub Actions UI or via the API. Create a new file named on_request_build.yml
in the .github/workflows
directory:
name: On-Request Build
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to build'
required: true
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.branch }}
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run build
run: npm run build
- name: Run tests
run: npm run test
Here’s what this workflow does:
name: On-Request Build
: Names the workflow.on:
: Defines the events that trigger the workflow.workflow_dispatch
: Allows manual triggering of the workflow.inputs:
: Defines input parameters.branch:
: Input parameter for specifying the branch to build.description
: Describes the input.required
: Specifies that the input is required.type
: Specifies the input type.
jobs:
: Defines the jobs to run.build
: The name of our job.runs-on: ubuntu-latest
: Specifies the runner.steps:
: Defines the steps within the job.name: Checkout code
:uses: actions/checkout@v3
: Checks out the code.with:
:ref: ${{ github.event.inputs.branch }}
: Specifies the branch to check out using the input parameter.
name: Set up Node.js
:uses: actions/setup-node@v3
: Sets up Node.js.with:
:node-version: '16'
: Specifies the Node.js version.
name: Install dependencies
:run: npm install
: Installs dependencies.name: Run build
:run: npm run build
: Runs the build script.name: Run tests
:run: npm run test
: Runs the tests.
With this workflow, you can go to the Actions tab in your GitHub repository, select “On-Request Build,” and manually trigger the workflow, specifying the branch you want to build. This gives you fine-grained control over when builds are performed.
Before we wrap up, let's quickly cover some best practices for using GitHub Actions:
- Use Actions from Trusted Sources: When using actions, especially those created by third parties, make sure they come from trusted sources. Look for actions with good documentation and a healthy community.
- Keep Workflows Modular: Break down complex workflows into smaller, more manageable jobs and steps. This makes it easier to debug and maintain your workflows.
- Use Environment Variables and Secrets: Avoid hardcoding sensitive information in your workflow files. Instead, use environment variables and secrets to store things like API keys and passwords.
- Test Your Workflows: Just like your application code, your workflows should be tested. Use tools like
act
to run your workflows locally and catch issues early. - Monitor Your Workflows: Regularly check the status of your workflows in the GitHub Actions UI. Set up notifications to be alerted when workflows fail.
Guys, setting up GitHub Actions for testing your application can significantly improve your development workflow. By automating builds, tests, and linting, you can ensure code quality, catch issues early, and streamline your release process. In this article, we’ve covered how to set up workflows for different scenarios, including full builds on main
and tagged releases, testing and linting for pull requests, and on-request builds for other changesets. By following these guidelines and best practices, you’ll be well on your way to creating a robust and efficient CI/CD pipeline for your projects. So, go ahead and start automating, and watch your productivity soar! Remember, automation is not just a tool; it’s a mindset that helps you focus on what truly matters: building great software.