In this challenge, you’ll create a GitHub Actions workflow that compiles and runs Go code across multiple operating systems.
You’ll also add a final job that performs cross-compilation to build binaries for multiple platforms.
You will complete the following steps in this challenge:
-
Create a new GitHub repository using the Go
.gitignoretemplate. -
Open the repository in the GitHub Web Editor to add code and workflows.
-
Create the file
main.gofile. -
Add a multi-job workflow triggered by
pushevents with four jobs:- One job each for Ubuntu, Windows, and macOS.
- A fourth job that runs after the first three jobs complete.
-
Push changes to the repository to trigger the workflow.
-
Review the Actions tab to confirm the workflow executed successfully on all platforms.
This challenge should take about 15 to 20 minutes to complete.
- Go to https://github.com and select New repository.
- Name the repository (e.g.,
multi-job-workflow). - Choose Public or Private visibility.
- Select Add .gitignore and choose the Go template.
- Leave other options as default and select Create repository.
- In your new repository, press the
.key on your keyboard to open the Web Editor. Alternatively, change the URL fromgithub.comtogithub.dev(e.g.,https://github.dev/your-username/multi-job-workflow).
- In the Web Editor, create a new file in the root of the repository named
main.go. - Copy and paste the following Go code into the file and save it.
package main
import (
"fmt"
"time"
)
type AWSRegion struct {
Name string
Timezone string
}
func main() {
// AWS regions in order from West to East
awsRegions := []AWSRegion{
// Americas
{"us-west-1", "America/Los_Angeles"},
{"us-west-2", "America/Los_Angeles"},
{"ca-central-1", "America/Toronto"},
{"us-east-1", "America/New_York"},
{"us-east-2", "America/New_York"},
{"sa-east-1", "America/Sao_Paulo"},
// Europe
{"eu-west-1", "Europe/Dublin"},
{"eu-west-2", "Europe/London"},
{"eu-west-3", "Europe/Paris"},
{"eu-central-1", "Europe/Berlin"},
{"eu-north-1", "Europe/Stockholm"},
// Asia-Pacific
{"ap-south-1", "Asia/Kolkata"},
{"ap-southeast-1", "Asia/Singapore"},
{"ap-northeast-2", "Asia/Seoul"},
{"ap-northeast-1", "Asia/Tokyo"},
{"ap-southeast-2", "Australia/Sydney"},
}
// Get current UTC time
now := time.Now()
fmt.Println("=========================================")
fmt.Println("Current UTC Time:", now.Format("2006-01-02 15:04:05 MST"))
fmt.Println("=========================================")
fmt.Println()
fmt.Println("=============================")
fmt.Println("AWS Data Center Current Times")
fmt.Println("=============================")
// Display times in the order specified
for _, region := range awsRegions {
loc, err := time.LoadLocation(region.Timezone)
if err != nil {
fmt.Printf("Error loading timezone for %s: %v\n", region.Name, err)
continue
}
regionalTime := now.In(loc)
fmt.Printf("%-15s | %s | %s\n",
region.Name,
regionalTime.Format("2006-01-02 15:04:05 MST"),
region.Timezone)
}
}- In the Web Editor, create the
.github/workflows/folder. - Create a new file named
multi-job.yml. - Use the following instructions to create the workflow configuration step-by-step.
-
Name the workflow
Multi-Job Workflow. -
Configure the workflow to trigger on
pushevents. -
Define four jobs:
ubuntu(runs onubuntu-latest)windows(runs onwindows-latest)macos(runs onmacos-latest)cross-compile(runs onubuntu-latestand depends on the first three)
-
Use
runs-onto configure the runner for each job.
name: Multi-Job Workflow
on: [push]
jobs:
ubuntu:
runs-on: ubuntu-latest
windows:
runs-on: windows-latest
macos:
runs-on: macos-latest
cross-compile:
runs-on: ubuntu-latestFor each of the first three jobs:
-
Under each job, add the following steps:
- Checkout the code:
- uses: actions/checkout@v4 - Set up Go environment:
- uses: actions/[email protected] - Compile the Go file:
- run: go build -o main main.go- Note: For the
windowsjob, usemain.exeinstead ofmain.
- Note: For the
- Run the compiled binary:
- run: ./main- Note: For the
windowsjob, use.\main.exeinstead of./main.
- Note: For the
- Checkout the code:
Ubuntu and macOS:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/[email protected]
with:
go-version: "1.20"
- name: Build Go binary
run: go build -o main main.go
- name: Run binary
run: ./mainWindows:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/[email protected]
with:
go-version: "1.20"
- name: Build Go binary
run: go build -o main.exe main.go
- name: Run binary
run: .\main.exe-
Define the fourth job with
runs-on: ubuntu-latest. -
Add the
needsattribute so that it waits for the three previous jobs to finish:needs: [ubuntu, windows, macos] -
Add the following steps:
- Checkout the code:
- uses: actions/checkout@v4 - Set up Go environment:
- uses: actions/[email protected] - Use a multi-line
runcommand to build binaries for each platform.
- Checkout the code:
cross-compile:
runs-on: ubuntu-latest
needs: [ubuntu, windows, macos]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/[email protected]
with:
go-version: "1.20"
- name: Cross-compile for all platforms
run: |
echo "Cross compiling for all platforms:"
GOOS=linux GOARCH=amd64 go build -o main-linux main.go
GOOS=windows GOARCH=amd64 go build -o main-windows.exe main.go
GOOS=darwin GOARCH=amd64 go build -o main-macos-intel main.go
Your complete workflow should be similar to the following:
name: Multi-Job Workflow
on: [push]
jobs:
build-ubuntu:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/[email protected]
with:
go-version: "1.20"
- name: Build Go binary
run: go build -o main main.go
- name: Run binary
run: ./main
build-windows:
runs-on: windows-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/[email protected]
with:
go-version: "1.20"
- name: Build Go binary
run: go build -o main.exe main.go
- name: Run binary
run: .\main.exe
build-macos:
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/[email protected]
with:
go-version: "1.20"
- name: Build Go binary
run: go build -o main main.go
- name: Run binary
run: ./main
cross-compile:
runs-on: ubuntu-latest
needs: [ubuntu, windows, macos]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/[email protected]
with:
go-version: "1.20"
- name: Cross-compile for all platforms
run: |
echo "Cross compiling for all platforms:"
GOOS=linux GOARCH=amd64 go build -o main-linux main.go
GOOS=windows GOARCH=amd64 go build -o main-windows.exe main.go
GOOS=darwin GOARCH=amd64 go build -o main-macos-intel main.go- In the Web Editor, stage and commit all your changes.
- Push the changes to your repository’s default branch (usually
main). - This push will trigger the workflow automatically.
- Go to your repository on GitHub and select the Actions tab.
- Select the most recent run triggered by your push.
- Review the logs for each job.
← 01_08 Challenge: Develop a Multi-Job Workflow | 02_01 Use an Action From the Marketplace →