Hello I'm Inzemam. This is the place for my blogposts. Check out my normal website for non blog related stuff.
March 28, 2022
Are you a lazy human like me? Great because then this is for you.
XClicker has existed for some time now and everytime I would create a new release, I would go through the same flow:
Being tired of doing the same procedure for every release and needing to build for other architectures, I created a workflow to do everything for me.
Before creating the release workflow, let's explain what the h*ll Github actions, workflows, and CI/CD is, and how to use them. (If you feel very big brain you can scroll straight to
CI/CD stands for Continuous Integration/Continuous Delivery. The XClicker workflow used a mix of both since the code gets compiled automatically (CI) and released (CD). Basically CI/CD is for automating tasks, and a workflow is the work CI/CD should do.
CI/CD is very often used for automating unit tests (ex. jest, cargo). An example is this rust workflow that builds, runs, and tests check code formatting every time a push to master happens, or when a pull request is opened.
1name: Rust 2 3on: 4 push: 5 branches: [ master ] 6 pull_request: 7 branches: [ master ] 8 9env: 10 CARGO_TERM_COLOR: always 11 12jobs: 13 build: 14 15 runs-on: ubuntu-latest 16 17 steps: 18 - uses: actions/checkout@v2 19 - name: Build 20 run: cargo build --verbose 21 - name: Test command 22 run: cargo run -- -c "echo test" 23 - name: Run tests 24 run: cargo test 25 - name: Clippy 26 run: cargo clippy --workspace -- -D warnings
Github provides a very epic way of automating your workflows with Github Actions. There are also CI/CD pipelines for other services like Azure Repos.
Let's create an incredibly simple rust application with some tests and a workflow.
1➜ cargo new rust-simple-workflow
Create a function called calculate_difficult_math like this and use it in the main function.
1fn calculate_difficult_math(a: i32, b: i32) -> i32 { 2 a + b 3} 4 5fn main() { 6 println!("Hello, world! {}", calculate_difficult_math(5, 5)); 7}
Now run the app and it should output something like this.
Now we can create a module called tests with a function called test_difficult_math.
1#[cfg(test)] 2mod tests { 3 // Importing all functions in the super scope 4 use super::*; 5 6 #[test] 7 fn test_difficult_math() { 8 // Panics if the left value is not equals to the right 9 assert_eq!(calculate_difficult_math(10, 5), 15); 10 } 11} 12
Full file
1fn calculate_difficult_math(a: i32, b: i32) -> i32 { 2 a + b 3} 4 5fn main() { 6 println!("Hello, world! {}", calculate_difficult_math(5, 5)); 7} 8 9#[cfg(test)] 10mod tests { 11 // Importing all functions in the super scope 12 use super::*; 13 14 #[test] 15 fn test_difficult_math() { 16 // Panics if the left value is not equals to the right 17 assert_eq!(calculate_difficult_math(10, 5), 15); 18 } 19}
Create a repository on Github with a readme, so it sets a main branch. Then press Actions and search Rust
Then press
Now initialize a Github repository in rust-simple-workflow and push it to Github.
1git init 2git remote add origin https://github.com/username/repo 3git pull origin master # Or HEAD:main 4git add . 5git commit -m "Initial commit" 6git push origin master # Or HEAD:main
Now go to the Github repository and you will see a small yellow dot. Press this and then
Hopefully, everything succeeded. And this is how to make a simple CI unit testing workflow.
Now to the fun part, let's create a workflow to automate releasing the rust project created before.
Open up the
Here is the new content. The comments should describe what happens.
1# Everytime a new tag is created that starts with v, It will run this action 2on: 3 push: 4 tags: 5 - 'v*' 6 7name: Create Release 8 9env: 10 CARGO_TERM_COLOR: always 11 12jobs: 13 build: 14 runs-on: ubuntu-latest 15 16 steps: 17 - uses: actions/checkout@v3 18 19 # First check that tests succeed 20 - name: Run tests 21 run: cargo test --verbose 22 23 # Build it 24 - name: Build 25 run: cargo build --verbose --release 26 27 # Create a github release with automatic generated release notes 28 - name: Create Release 29 uses: softprops/action-gh-release@v0.1.14 30 env: 31 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 with: 33 generate_release_notes: true 34 draft: false 35 prerelease: false 36 files: | 37 target/release/rust-simple-workflow
You can create a new tag that starts with v and push it now when you have this workflow.
1git tag v1.0.0 2git push origin --tags
Now go to the Github repository and you will see the yellow dot again. Click details and you will be presented with what happens. After a bit of time, you will see a new release is created by github-actions with the compiled asset. Now, this is just for the platform the ubuntu container is running, which in this case is amd64. If you would like to build it for other platforms you would have to look into cross or uraimo/run-on-arch-action (used for XClicker)
Thanks for reading and I hope you learned something new!