Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Adding ci/cd pipeline using dagger #37

Merged
merged 21 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 82 additions & 21 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,33 +1,94 @@
name: Build

on:
# Build only triggers once lint and test workflow successfully completes
workflow_run:
workflows: [Lint]
types:
- completed

jobs:
dagger-build:
dagger-build-satellite:
runs-on: ubuntu-latest
# unless you specify the success on the event,
# unless you specify the success on the event,
# this job will also run if the lint workflow was skipped(which is also the case if the condition for the file extension type is false).
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '>=1.22'

- name: Update CA certificates
run: |
sudo apt-get update
sudo apt-get install -y ca-certificates
sudo update-ca-certificates

- name: Install curl and Docker
run: |
sudo apt-get install -y curl
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

- name: Verify Docker installation
run: docker --version

- name: Install Dagger CLI
run: |
cd /usr/local
curl -L https://dl.dagger.io/dagger/install.sh | sudo sh
cd -
Mehul-Kumar-27 marked this conversation as resolved.
Show resolved Hide resolved

- name: Build Satellite with Dagger
run: dagger run go run ci/main.go satellite
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_USERNAME: ${{ github.repository_owner }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_SHA: ${{ github.sha }}

dagger-build-ground-control:
# unless you specify the success on the event,
# this job will also run if the lint workflow was skipped(which is also the case if the condition for the file extension type is false).
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
-
name: Checkout repository
uses: actions/checkout@v4
-
name: Setup go
uses: actions/setup-go@v4
with:
go-version: '>=1.22'
-
name: Install
run: go get dagger.io/dagger@latest
-
name: Install Dagger CLI
run: cd /usr/local && { curl -L https://dl.dagger.io/dagger/install.sh | sh; cd -; }
-
name: Build with Dagger
run: dagger run go run ci/main.go

- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '>=1.22'

- name: Update CA certificates
run: |
sudo apt-get update
sudo apt-get install -y ca-certificates
sudo update-ca-certificates

- name: Install curl and Docker
run: |
sudo apt-get install -y curl
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

- name: Verify Docker installation
run: docker --version

- name: Install Dagger CLI
run: |
cd /usr/local
curl -L https://dl.dagger.io/dagger/install.sh | sudo sh
cd -

- name: Build Ground Control with Dagger
run: dagger run go run ci/main.go ground-control
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_USERNAME: ${{ github.repository_owner }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_SHA: ${{ github.sha }}
9 changes: 9 additions & 0 deletions ci/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package config

type Config struct {
GithubToken string
GithubUser string
Github_Repository string
Github_SHA string
AppName string
}
131 changes: 131 additions & 0 deletions ci/ground_control/ground_control.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package ground_control_ci

import (
"context"
"fmt"
"log/slog"
"os"
"os/exec"
"path/filepath"

"golang.org/x/oauth2"

"container-registry.com/harbor-satellite/ci/config"
"dagger.io/dagger"
"github.com/google/go-github/v39/github"
)

const BinaryPath = "./bin"
const DockerFilePath = "./ci/ground_control/Dockerfile"

type GroundControlCI struct {
config *config.Config
client *dagger.Client
ctx *context.Context
}

func NewGroundControlCI(client *dagger.Client, ctx *context.Context, config *config.Config) *GroundControlCI {
return &GroundControlCI{
client: client,
ctx: ctx,
config: config,
}
}

func (s *GroundControlCI) StartGroundControlCI() error {
err := s.ExecuteTests()
if err != nil {
return err
}
err = s.BuildGroundControl()
if err != nil {
return err
}
err = s.ReleaseBinary()
if err != nil {
return err
}

return nil
}

func (s *GroundControlCI) ExecuteTests() error {
slog.Info("Running Tests")

cmd := exec.Command("go", "test", "./...", "-v", "-count=1")

_, err := cmd.CombinedOutput()

if err != nil {
slog.Error("Error executing tests: ", err.Error(), ".")
return err
}

slog.Info("Tests executed successfully.")
return nil
}

func (s *GroundControlCI) BuildGroundControl() error {

currentDir, err := os.Getwd()
if err != nil {
return err
}
groundControlDir := fmt.Sprintf("%s/%s", currentDir, "ground-control")
sourceDir := s.client.Host().Directory(groundControlDir)

binaryBuildContainer := s.client.Container().
From("golang:1.22").
WithDirectory("/ground_control", sourceDir).
WithWorkdir("/ground_control").
WithExec([]string{"go", "build", "-o", fmt.Sprintf("/%s/ground_control", BinaryPath), "."})

_, err = binaryBuildContainer.File(fmt.Sprintf("/%s/ground_control", BinaryPath)).
Export(*s.ctx, fmt.Sprintf("/%s/%s/ground_control", currentDir, BinaryPath))

if err != nil {
return err
}
slog.Info("Binary built successfully")
return nil
}
Mehul-Kumar-27 marked this conversation as resolved.
Show resolved Hide resolved

func (s *GroundControlCI) ReleaseBinary() error {
slog.Info("Releasing binary to GitHub")
ctx := *s.ctx
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: s.config.GithubToken},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
// Create a new release
release, _, err := client.Repositories.CreateRelease(ctx, s.config.GithubUser, "harbor-satellite", &github.RepositoryRelease{
TagName: github.String("v" + s.config.Github_SHA[:6]),
Name: github.String(s.config.AppName + " Release"),
Body: github.String("Automated release by CI"),
Draft: github.Bool(false),
Prerelease: github.Bool(false),
})
if err != nil {
return fmt.Errorf("failed to create GitHub release: %v", err)
}

// Open the binary file
binaryPath := filepath.Join(BinaryPath, "ground_control")
file, err := os.Open(binaryPath)
if err != nil {
return fmt.Errorf("failed to open binary file: %v", err)
}
defer file.Close()

// Upload the binary as an asset
_, _, err = client.Repositories.UploadReleaseAsset(ctx, s.config.GithubUser, "harbor-satellite", *release.ID, &github.UploadOptions{
Name: "ground_control",
}, file)
if err != nil {
return fmt.Errorf("failed to upload release asset: %v", err)
}

slog.Info("Binary released successfully to GitHub")
return nil
}
53 changes: 44 additions & 9 deletions ci/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,40 @@ package main

import (
"context"
"fmt"
"log/slog"
"os"

"container-registry.com/harbor-satellite/ci/config"
ground_control_ci "container-registry.com/harbor-satellite/ci/ground_control"
satellite_ci "container-registry.com/harbor-satellite/ci/satellite"
"dagger.io/dagger"
)

func main() {
if len(os.Args) < 2 {
slog.Error("Please provide the app name (satellite or ground-control) as an argument.")
os.Exit(1)
}

appName := os.Args[1]

token := os.Getenv("GITHUB_TOKEN")
user := os.Getenv("GITHUB_USERNAME")
repo := os.Getenv("GITHUB_REPOSITORY")
sha := os.Getenv("GITHUB_SHA")

if token == "" || user == "" || repo == "" || sha == "" {
panic(fmt.Sprintf("Missing required environment variables: GITHUB_TOKEN=%s, GITHUB_USERNAME=%s, GITHUB_REPOSITORY=%s, GITHUB_SHA=%s", token, user, repo, sha))
}

config := config.Config{
GithubToken: token,
GithubUser: user,
Github_Repository: repo,
Github_SHA: sha,
AppName: appName,
}
ctx := context.Background()

// initialize Dagger client
Expand All @@ -18,15 +45,23 @@ func main() {
}
defer client.Close()

// use a golang:1.19 container
// get version
// execute
golang := client.Container().From("golang:1.21").WithExec([]string{"go", "version"})
switch appName {
case "satellite":
satelliteCI := satellite_ci.NewSatelliteCI(client, &ctx, &config)
err := satelliteCI.StartSatelliteCI()
if err != nil {
slog.Error("Error executing Satellite CI: " + err.Error())
os.Exit(1)
}

version, err := golang.Stdout(ctx)
if err != nil {
panic(err)
case "ground-control":
ground_control_ci := ground_control_ci.NewGroundControlCI(client, &ctx, &config)
err := ground_control_ci.StartGroundControlCI()
if err != nil {
slog.Error("Error executing Ground Control CI: " + err.Error())
os.Exit(1)
}
default:
slog.Error("Invalid app name. Please provide either 'satellite' or 'ground-control'.")
}
// print output
slog.Info("Hello from Dagger!", "version", version)
}
Loading