GitHub Actions is a widely adopted platform for automating development workflows, offering flexibility through event-driven YAML configurations. While running workflows on GitHub’s hosted infrastructure is standard practice, relying solely on cloud execution can slow down iteration and make debugging cumbersome.
Testing GitHub Actions locally provides a faster and more controlled alternative. It enables developers to validate workflows, troubleshoot issues, and fine-tune automation steps before pushing changes to a repository.
This article explores various methods for running GitHub Actions locally and covers official tools like the GitHub Actions Toolkit, along with advanced cross-browser testing with BrowserStack.
Benefits of running GitHub Actions Locally
GitHub Actions is a powerful automation platform provided by GitHub, designed to streamline and automate various tasks within the software development lifecycle.
It allows developers to define workflows as code, specifying a series of steps to be executed in response to specific events or triggers. Workflows can be triggered by events like code pushes, pull requests, issue creations, scheduled intervals, and more.
- Faster Iteration: Quickly test and validate workflows without pushing changes to GitHub, speeding up the development process.
- Debugging: Easily debug actions by stepping through code, inspecting variables, and tracking execution flow, simplifying troubleshooting of complex workflows.
- Cost Savings: Reduce unnecessary workflow runs on GitHub, optimizing resource usage and saving costs, especially during development and debugging.
- Offline Availability: Develop and test workflows without internet access, ensuring uninterrupted progress even in limited or unreliable connectivity situations.
- Integration Testing: Test the integration of different actions or workflows in a local test environment, ensuring seamless data transfer and validating overall automation behavior.
- Enhanced Security: Maintain control over the environment and data, allowing for secure testing of workflows with sensitive information.
- Collaboration: Share and test workflows locally, enabling faster feedback loops and smoother development processes.
How to Run GitHub Actions Locally (for Windows, Mac, and Linux)
The following steps outline how to run GitHub Actions locally across major operating systems using the act CLI tool.
Step 1: Install Docker
Ensure Docker is installed and running on the system. act uses Docker to emulate GitHub-hosted runners. You can download Docker here.
Step 2: Install the act CLI Tool
The act CLI allows workflows to run locally by simulating GitHub Actions events.
For macOS, install via Homebrew:
brew install act
For Windows, install via Chocolatey:
choco install act-cli
For Linux, use the install script:
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
Step 3: Clone the GitHub Repository Locally
Clone the project that contains the workflow to be tested:
git clone https://github.com/your-username/your-repo.git cd your-repo
Step 4: Confirm Workflow File Exists
Verify that the repository contains a valid workflow file at:
.github/workflows/workflow-name.yml
Step 5: Create a .secrets File (If Needed)
If the workflow uses GitHub secrets, create a .secrets file in the root directory of the project.
Step 6: Run the Workflow using act
To run the workflow locally, execute:
act
Step 7: Monitor Execution Logs
Observe the terminal output to monitor each job and step. act displays logs similar to GitHub’s UI, including command outputs and errors.
How to test GitHub Actions Locally?
Here are different methods to Test Gitlab Locally:
Methods to Test Gitlab Locally:
- Using the GitHub Actions Toolkit
- Using a Third-Party Tool- Act CLI
- Running GitHub Actions Locally with BrowserStack
Method 1. Using the GitHub Actions Toolkit
Prerequisites:
Make sure you have Node.js and npm (Node Package Manager) installed on our local machine.
Step 1: Install the GitHub Actions Toolkit
To begin, install the @actions/core package from the GitHub Actions Toolkit as a development dependency in our project. Open our terminal or command prompt and navigate to our project’s root directory. Run the following command:
npm install --save-dev @actions/core
This will install the necessary package for GitHub actions test locally .
Step 2: Write a Test Script
Next, create a test script that uses the GitHub Actions Toolkit to execute and validate our workflow locally. Let’s assume you have a GitHub Actions workflow file named main.workflow in our repository.
Create a file named test.js and add the following code:
const core = require('@actions/core'); const exec = require('@actions/exec'); async function run() { try { // Set the input variables (if any) core.getInput('myInputVariable'); // Execute the steps of our workflow await exec.exec('echo', ['Hello, World!']); // Add more steps as necessary // Set the output variables (if any) // Set the output variables (if any) core.setOutput('myOutputVariable', 'Hello from local testing!'); } catch (error) { core.setFailed(error.message); } } run();
- In this example, you import the core module from the GitHub Actions Toolkit, which provides various utility functions for working with inputs, outputs, and the execution environment.
- The script executes the steps defined in the workflow, such as running commands (echo ‘Hello, World!’) and setting output variables (core.setOutput(‘myOutputVariable’, ‘Hello from local testing!’)).
Step 3: Run the Test Script
To run the test script and simulate the workflow execution locally, execute the following command in our terminal or command prompt:
node test.js
- This will execute the test script and provide output and feedback based on the steps defined in the script.
- By running the test script locally, you can validate the behavior of our GitHub Actions workflow, test different inputs and outputs, and debug any issues that arise.
- This allows for faster iterations and troubleshooting without the need to push changes to the GitHub repository.
Note: The example above demonstrates testing a simplified workflow locally. In real-world /bluescenarios, our workflows may involve more complex logic, integrations with other tools or services, and multiple steps or actions.
Method 2. Using a Third-Party Tool – Act CLI
act is a lightweight command-line tool developed by the open-source community (nektos/act) that allows you to run GitHub Actions workflows locally. It emulates the GitHub-hosted runner environment, enabling developers to test, debug, and validate workflows before pushing them to a repository. This tool supports key features like event triggers, matrix builds, environment variables, and more. It’s useful for quickly iterating on your .yml workflow without waiting for GitHub to run it remotely.
Prerequisite: Install Docker
Before using act, make sure Docker is installed and running. act uses Docker containers to emulate the GitHub-hosted runner environment.
You can check Docker installation via:
docker --version
If not installed, download Docker from the official site and install it based on your OS.
Step 1: Install act
The first step is to install act, a command-line tool that runs GitHub Actions workflows locally.
For macOS (Homebrew): brew install act For Windows (Chocolatey): choco install act-cli
Step 2: Prepare Your Workflow
Ensure you have a GitHub repository cloned locally with a valid workflow file inside .github/workflows/. Typically, the file looks like this: .github/workflows/ci.yml
name: CI Workflow on: [push] jobs: build: runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v3 - name: Run a script run: echo "Hello from GitHub Actions!"
Step 3: Run the Workflow Locally
Navigate to the root of your cloned repo in your terminal:
cd path/to/your/repo To run the default workflow: act To run a specific event (e.g., push): act push To see what will happen without executing: act --dryrun To pass secrets or inputs using a .secrets file: .secrets MY_SECRET=abc123 Then run: act -s MY_SECRET=abc123
Read More: How to run test on GitLab CI Locally
Method 3. Running GitHub Actions Locally with BrowserStack
- Running GitHub Actions locally with BrowserStack allows us to leverage BrowserStack cloud infrastructure to execute our workflows on various browsers and devices.
- This method is particularly useful for testing web applications and ensuring cross-browser compatibility.
A more detailed explanation of how to run GitHub Actions locally with BrowserStack follows:
Step 1: Set Up a Local Development Environment
Before running GitHub Actions locally with BrowserStack, ensure that you have a local development environment set up on our machine. This typically includes an operating system, a code editor or IDE, and the necessary tools and dependencies for our project.
Step 2: Configure GitHub Actions Workflow for BrowserStack
Modify our GitHub Actions workflow file to incorporate BrowserStack’s browser-specific testing capabilities. BrowserStack provides pre-configured GitHub Actions actions that allow us to specify the browsers and devices on which you want to run our tests.
Example of how to configure our workflow to run tests using BrowserStack:
name: BrowserStack Local Testing on: [push] jobs: test: runs-on: ubuntu-latest steps: - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '14' - name: Checkout code uses: actions/checkout@v2 - name: Install dependencies run: npm ci - name: Run tests uses: browserstack/github-action@v2 with: browsers: chrome, firefox build-name: GitHub Actions Local Testing timeout: 300
In this example, the workflow is triggered on every push event. It runs on the latest Ubuntu environment, sets up Node.js, checks out the code, installs dependencies, and then uses the browserstack/github-action action to run tests on Chrome and Firefox browsers. You can customize the browsers, build names, timeout, and other parameters based on our requirements.
Step 3: Obtain BrowserStack Credentials
To use BrowserStack with GitHub Actions, you need to obtain our BrowserStack credentials. Sign up for a BrowserStack account if you don’t have one already. Once you have our credentials (BrowserStack username and access key), you’ll need to store them securely as secrets in our GitHub repository. Follow GitHub’s documentation on how to add and manage repository secrets.
Step 4: Run GitHub Actions Locally with BrowserStack
To run the GitHub Actions workflow locally with BrowserStack, follow these steps:
1. Set up our local development environment and ensure that our project dependencies and BrowserStack-specific configurations are in place.
2. Open our terminal or command prompt and navigate to our project’s root directory.
Execute the following command:
npx github-action-local-runner run -e BROWSERSTACK_USERNAME=<username> -e BROWSERSTACK_ACCESS_KEY=<access-key>
3. Replace <username> and <access-key> with our actual BrowserStack credentials. The github-action-local-runner tool emulates the GitHub Actions environment locally and executes the workflow with the specified credentials.
4. The tool will simulate the GitHub Actions runtime and communicate with BrowserStack’s infrastructure to run tests on the specified browsers and devices. The test results and logs will be displayed in the terminal.
Differences between Local and GitHub-hosted Environments
There are several key differences between running GitHub Actions locally and using GitHub-hosted environments:
Criteria | Running GitHub Actions Locally | GitHub-Hosted Environments |
---|---|---|
Execution Environment | – Can be set up to closely resemble the production environment. – Provides control over the execution environment. – Allows customization of hardware and software configurations. | – Standardized environments managed by GitHub. – Offers consistent and predictable execution environments. – Eliminates the need for local infrastructure setup and management. |
Resource Allocation | – More flexibility in allocating resources. – Can utilize local hardware or infrastructure resources. | – Provides predefined resource allocation based on environment type. – Offers scalable resources based on workload demands. |
Scalability | – Limited to available resources on the local machine or infrastructure. – Scaling may require additional setup or configuration. | – Provides dynamic scalability managed by GitHub. – GitHub manages the infrastructure and ensures availability. |
Internet Access | – Controlled network connectivity as per local network setup. | – GitHub-hosted environments have internet access by default. |
Cost | – Potential cost savings by optimizing resource usage. | – Usage-based costs depending on the environment and workflow runs. |
Debugging and Iteration | – Real-time debugging and faster iterations. | – Provides debugging options, but with a longer feedback loop as changes need to be pushed to trigger a workflow and examine results on GitHub. |
Collaboration | – Enables team collaboration without affecting the shared environment. | – Facilitates collaboration through shared infrastructure. |
Management | – Requires setup and maintenance of the local environment. | – Managed by GitHub with availability and maintenance handled by GitHub. |
Consider these factors when choosing between running GitHub Actions locally or using GitHub-hosted environments. It depends on our specific requirements, project needs, available resources, and the level of control and customization you need over the execution environment.
Benefits of Running GitHub Actions Locally with BrowserStack
- Comprehensive Browser Testing: You can test our web application on a wide range of browsers and devices without the need for local infrastructure or virtual machines.
- Faster Feedback Loop: Running tests locally allows for faster iterations and immediate feedback, enabling us to identify and fix issues quickly.
- Cost Savings: By utilizing BrowserStack’s cloud-based infrastructure for testing, you can save costs on setting up and maintaining local testing environments.
- Cross-Browser Compatibility: Running tests on different browsers helps ensure that our application works consistently across various platforms, reducing the chances of browser-specific issues.
- Easy Integration: BrowserStack provides pre-configured GitHub Actions actions, making it seamless to integrate their testing capabilities into our existing workflows.
By following these steps and leveraging BrowserStack’s cloud-based testing infrastructure, you can efficiently run GitHub Actions workflows locally and achieve comprehensive cross-browser testing for our web applications.
Integrate GitHub Actions with BrowserStack
Integrating Local Testing into the Development Workflow
Integrating local testing into the development workflow is an effective way to catch bugs and issues early in the development process. It helps identify problems quickly, allows for faster iterations, and reduces the risk of pushing faulty code to production.
An overview of how local testing can be integrated into the development workflow:
Step 1. Continuous Integration (CI) and Version Control:
- Utilize a version control system, such as Git, to manage our codebase. Maintain separate branches for development, testing, and production environments.
- Set up a CI system, like GitHub Actions, Jenkins, or Travis CI, to automate the execution of tests and checks whenever code changes are pushed to the repository.
- Configure the CI system to trigger local tests on developers’ machines before committing and pushing changes.
Step 2. Local Development Environment:
- Developers should maintain a consistent and isolated local development environment that mirrors the production environment as closely as possible.
- Install necessary dependencies, libraries, and tools required for local testing.
- Ensure that the local development environment is properly configured to execute tests effectively.
Step 3. Writing Unit Tests:
- Developers should write unit tests for their code components to ensure individual functions, methods, or modules work as expected.
- Use testing frameworks and libraries relevant to the programming language being used.
- Incorporate test-driven development practices, where tests are written before writing the actual code.
Step 4. Running Unit Tests Locally:
- Developers should run unit tests locally before pushing code changes to the repository.
- Execute unit tests using appropriate testing frameworks or tools in the local development environment.
- Validate the functionality, correctness, and expected behavior of the code components being tested.
Read More: Overcoming Challenges of Local Testing
Step 5. Integration and End-to-End Testing:
- Develop integration and end-to-end tests that cover the interaction between different components or services in your application.
- Use testing frameworks, tools, or libraries specifically designed for integration and end-to-end testing.
- Run integration and end-to-end tests locally to identify any issues related to the interaction and communication between different parts of the application.
Step 6. Test Automation:
- Automate the execution of local tests using scripts, build systems, or task runners to streamline the testing process.
- Incorporate test automation into our local development environment to ensure tests can be executed easily and consistently.
Step 7. Debugging and Issue Resolution:
- When local tests fail, utilize debugging tools and techniques available in the development environment to identify the root cause of failures.
- Analyze test failures, debug code, and fix issues locally to ensure code quality and prevent regressions.
Step 8. Test Coverage and Reporting:
- Track and analyze test coverage metrics to ensure that critical parts of the codebase are adequately tested.
- Generate test reports to provide insights into the test results, including pass/fail status, code coverage, and performance metrics.
- Use code quality and coverage analysis tools to identify areas of improvement and enhance test effectiveness.
Automating Local Testing with scripts or tooling
Automating local testing with scripts or tooling is an efficient way to streamline the testing process and ensure consistent execution of tests. Let’s consider a real-time example of automating local testing for a web application built with React.js using the testing frameworks Jest and React Testing Library.
Step 1. Identify Testing Requirements:
- You have a React.js application that includes components, state management, and API interactions.
- You need to write unit tests for individual components, integration tests for API interactions, and end-to-end tests for critical user flows.
Step 2. Set Up the Local Development Environment:
- Install Node.js and npm (Node Package Manager) on your machine.
- Create a new directory for your project and initialize it with npm.
Step 3. Write Test Cases:
- Create a folder structure for organizing your tests, such as src/tests/unit, src/tests/integration, and src/tests/end-to-end.
- Write test files for each component, API interaction, or user flow you want to test.
- For example, in src/tests/unit folder, create a file Button.test.js to test the functionality of a Button component.
Step 4. Create Test Runner Scripts or Task Configurations:
- In the project’s root directory, create a script file called test.sh (for a Unix-based system) or test.bat (for Windows).
- Define the necessary commands to set up the test environment, run the tests, and generate test reports.
- For example, the test.sh script may include commands like:
# Install dependencies npm install # Run unit tests npm run test:unit # Run integration tests npm run test:integration # Run end-to-end tests npm run test:e2e
Step 5. Configure Test Environment:
- Set up a test environment configuration file, such as src/tests/test.env, that includes test-specific environment variables.
- Configure the environment variables to use a separate test API endpoint or mock API responses for integration testing.
Step 6. Run Tests Locally:
- Open a terminal or command prompt and navigate to your project’s root directory.
- Execute the test runner script by running the command:
sh test.sh
This will run the script and execute the defined test commands.
Step 7. Test Reporting and Analysis:
- Jest, the testing framework, provides built-in test reporting capabilities.
- Configure Jest to generate test reports in formats like JUnit XML or HTML reports.
- After running the tests, review the generated reports to analyze the test results.
Step 8. Test Automation Integration:
- Integrate the test runner script into your CI system, such as GitHub Actions, Jenkins, or GitLab CI/CD.
- Set up hooks or triggers to automatically execute the script on code pushes or pull requests.
- Configure the CI system to display test results and notify the team of any failures.
Step 9. Continuous Improvement:
- Regularly update and expand your test suite as new components and features are added or existing code changes.
- Refactor the test runner script to enhance performance, incorporate additional tools like code coverage analysis, or enable parallel test execution.
This example demonstrates how to automate local testing for a React.js web application using Jest and React Testing Library. The process can be adjusted based on your specific application’s structure, testing requirements, and chosen testing frameworks/tools.
Read More: How to test Website on Mobile Locally?
Incorporating local testing with BrowserStack into CI pipelines
Incorporating local testing with BrowserStack into CI pipelines allows us to run automated tests on different browsers and devices hosted on BrowserStack’s cloud infrastructure. A high-level overview of how you can integrate local testing with BrowserStack into your CI pipelines:
Step 1. Set Up BrowserStack Account:
- Sign up for a BrowserStack account and obtain your access credentials (username and access key).
- Install the BrowserStack Local binary by following the instructions provided by BrowserStack.
Step 2. Configure CI Environment:
- In your CI environment (e.g., GitHub Actions), navigate to the repository’s settings.
- Add the BrowserStack access credentials as environment variables, typically named BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY.
- Ensure the credentials are securely stored and not exposed in the repository.
Step 3. Write Test Scripts:
- Assume you have a Node.js web application with end-to-end tests written using Cypress.
- In the project’s root directory, create a Cypress configuration file named cypress.json.
- Configure the Cypress configuration file to use BrowserStack as the target browser.
- Example cypress.json
{ "baseUrl": "http://localhost:3000", "browser": "chrome", "browserStack": true, "browserStackOptions": { "userName": "${process.env.BROWSERSTACK_USERNAME}", "accessKey": "${process.env.BROWSERSTACK_ACCESS_KEY}", "local": "true" } }
Step 4. Set Up CI Pipeline:
- In your CI pipeline configuration file (e.g., .github/workflows/main.yml for GitHub Actions), add a step to execute the end-to-end tests.
- Example GitHub Actions configuration:
name: CI Pipeline on: push: branches: - main jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Install dependencies run: npm install - name: Run end-to-end tests run: npm run cy:run
Step 5. Establish Connection to BrowserStack:
- Before running the tests, establish a connection to BrowserStack’s cloud infrastructure using the BrowserStack Local binary.
- Add the following command to your CI pipeline configuration before running the end-to-end tests:
- name: Establish BrowserStack connection run: ./BrowserStackLocal --key ${{ secrets.BROWSERSTACK_ACCESS_KEY }} --local-identifier my-local-identifier
Step 6. Execute Local Tests on BrowserStack:
- When the end-to-end test command is executed, Cypress will use the configured BrowserStack settings to run the tests on the specified browsers and devices in BrowserStack’s cloud.
- Example command in package.json to run Cypress end-to-end tests:
"scripts": { "cy:run": "cypress run" }
Step 7. Retrieve Test Results:
- After the test execution, Cypress will provide the test results, including any logs or screenshots captured during the tests.
- Cypress automatically saves the test results in the cypress/results folder by default.
Step 8. Analyze Test Results and Generate Reports:
- Use the Cypress reporting options to generate reports based on the test results.
- For example, you can generate an HTML report using a Cypress reporting plugin like cypress-mochawesome-reporter.
Step 9. Cleanup and Teardown:
- After the test execution is complete, ensure to properly clean up and tear down the connection to BrowserStack’s cloud.
- Add a step to your CI pipeline configuration to stop the BrowserStack Local binary:
- name: Stop BrowserStack Local run: ./BrowserStackLocal --local-identifier my-local-identifier --daemon stop
- This example demonstrates how to incorporate local testing with BrowserStack into a CI pipeline for running end-to-end tests with Cypress.
- You can adapt this process to our specific CI tool and testing framework, ensuring the necessary configurations and commands are in place to connect to BrowserStack and execute the tests on their cloud infrastructure.
Conclusion
Local testing and incorporating it into CI pipelines, along with the use of GitHub Actions and BrowserStack, bring several advantages to the software development process. Local testing allows for quicker validation of code changes, early bug detection, and reduced reliance on remote testing environments. GitHub Actions streamline automation tasks and enable efficient CI/CD workflows directly within the GitHub platform.
Additionally, running GitHub Actions locally facilitates faster feedback and improved debugging capabilities. Integration with BrowserStack extends testing coverage across different browsers and devices, ensuring a consistent user experience. Overall, these approaches enhance developer productivity, code quality, and software delivery efficiency.