Continuous Integration (CI) and Continuous Deployment (CD) are essential practices in modern software development that help automate the testing and deployment of applications. Integrating Hardhat, a popular Ethereum development framework, into a CI/CD pipeline allows for automated testing and deployment of smart contracts. This guide will walk you through the process of setting up a CI/CD pipeline using GitHub Actions as an example.

Prerequisites

  • A Hardhat project with smart contracts and tests already set up.
  • A GitHub repository to host your Hardhat project.
  • Basic knowledge of GitHub Actions.

Setting Up Your Hardhat Project

Ensure you have a Hardhat project with the necessary smart contracts and tests. If you haven't set up a Hardhat project yet, you can do so by following these steps:

mkdir my-hardhat-project
cd my-hardhat-project
npm init --yes
npm install --save-dev hardhat
npx hardhat

Create a simple smart contract in the contracts directory, such as Greeter.sol:

pragma solidity ^0.7.0;

contract Greeter {
string greeting;

constructor(string memory _greeting) {
greeting = _greeting;
}

function greet() public view returns (string memory) {
return greeting;
}

function setGreeting(string memory _greeting) public {
greeting = _greeting;
}
}

Next, create a test file in the test directory to test your smart contract:

const { expect } = require("chai");

describe("Greeter", function () {
it("Should return the new greeting once it's set", async function () {
const Greeter = await ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, world!");
await greeter.deployed();

expect(await greeter.greet()).to.equal("Hello, world!");

const setGreetingTx = await greeter.setGreeting("Hola, mundo!");

// wait until the transaction is mined
await setGreetingTx.wait();

expect(await greeter.greet()).to.equal("Hola, mundo!");
});
});

Creating GitHub Actions Workflow

To set up a CI/CD pipeline using GitHub Actions, you need to create a workflow file in your repository. Follow these steps:

  • In your Hardhat project, create a directory called .github/workflows:
mkdir -p .github/workflows
  • Create a new file named ci.yml inside the workflows directory:
contracts0

Open ci.yml and add the following content:

contracts2

Explanation of the Workflow

  • name: The name of the workflow.
  • on: Specifies the events that trigger the workflow. In this case, it runs on pushes and pull requests to the contracts3 branch.
  • jobs: Defines the jobs that will run in the workflow. Here we have a single job named test.
  • runs-on: Specifies the type of virtual machine to use. We use contracts5.
  • steps: A series of steps that will be executed in order:
    • Checkout the code from the repository.
    • Set up Node.js environment.
    • Install dependencies using npm.
    • Run the Hardhat tests using the command contracts6.

Triggering the CI/CD Pipeline

Once you have set up the workflow file, every time you push changes to the contracts3 branch or create a pull request, GitHub Actions will automatically trigger the CI/CD pipeline. You can check the progress and results of the workflow in the "Actions" tab of your GitHub repository.

Deploying Smart Contracts

If you want to extend your CI/CD pipeline to include deployment of your smart contracts, you can add another job to your ci.yml file. For example, you can deploy to a test network after running tests:

contracts9

Make sure to configure your deployment script and set up any necessary environment variables or secrets in your GitHub repository settings for deployment to work correctly.

Conclusion

Integrating Hardhat with a CI/CD pipeline using GitHub Actions allows for automated testing and deployment of your smart contracts. This setup ensures that your code is always tested and deployed in a consistent manner, improving the reliability and efficiency of your development process.