So you want to write and deploy smart contracts?
As a professional, do your best to use general best practices for the best software. There is no need to reinvent the wheel and change the processes that work. Sometimes we need to adjust our tooling. That’s what this article is about.
For our sample project, let’s set up this environment from scratch.
Repository settings
Starting with two repositories is considered a good idea. One is public for the main activity, the second is private and also holds the codebase. This is because some activities in the project should not be discussed publicly, for example live vulnerabilities/security patches that may affect users. This approach helps prevent hackers who can exploit bugs disclosed in pull requests before they are fixed in the released code.
To avoid complicating this tutorial, we will focus only on the public repository (GitHub).
Let’s step through the repository setup and consider changing important parameters, such as branch protection rules or access control for your team.
Project initialization
Clone an empty repository and enter it. In the repository folder, initialize the project’s template with:
This command prepares all the necessary folders, including the .gitignore file.
Write code
Now you are ready to write code. Let’s start with the one created next. OpenZeppelin Solidity Wizard There are some changes (bugs):
This code includes some packages, so you’ll need to add them using npm (don’t forget to add node_modules to .gitignore).
Once you install the package, you can test compilation.
As it stands, I have a working project with the following structure:
Write a test
First we need to initialize pytype for our source code.
Then we’ll write some basic tests.
And you can run your tests using:
Write a deployment script
We will be deploying the contract on the Holesky testnet. Writing a deployment script is very similar to writing tests.
Before deploying, you can set the private key in an .env file, retrieve it using the dotenv library, and test your deployment.
Since everything works as expected – testing, deploying, compiling – you can proceed to write a pipeline to automate these steps.
Create a Pipeline
Let’s start by creating a folder for our pipeline.
Then create a pipeline.yml file in this folder.
We have two jobs. One is a pull request to master test and analyze the new code that will be merged. The second task is for deployment and is triggered only when merging/pushing to master. we are using Wake Settings Action Set up an environment for testing and deployment. Then we are using professional ones. Wake detection task For scanning code for vulnerabilities. The deployment part requires passing the private key along with dotenv via GitHub secret. That secret must be set in your repository settings.
Once you’ve set up your secret, let’s get started.
distribution
Everything is set. You can check out different branches and push your codebase. After the push, nothing is triggered because there is no pipeline defined for this action. That’s expected.
After creating a pull request, you will see the pipeline triggered (skip deployment).
Obviously, we haven’t run any static analysis before, so we can see bugs being detected in the pipeline and attached to the pull request.
Therefore, depending on your repository policy, you may not be able to merge to master until the issue is fully resolved.
Let’s go back to the code to fix the problem. Remove unused imports and replace tx.origin with msg.sender.
You will now see that you are ready to deploy.
Let’s merge!
You have successfully deployed your contract through GitHub Actions.
final remarks
This tutorial showed you how to use GitHub Actions to enhance your CI/CD process.
These actions will help make your project more sustainable and efficient. The examples provided are purely for informational purposes, so it’s now up to you to find what works best for your project.