Skip to content

Commit

Permalink
Merge pull request #37 from Mehul-Kumar-27/dagger-ci
Browse files Browse the repository at this point in the history
Feat: Adding ci/cd pipeline using dagger
  • Loading branch information
Vad1mo authored Sep 3, 2024
2 parents ec1e82c + 86381c8 commit 02ba374
Show file tree
Hide file tree
Showing 15 changed files with 659 additions and 71 deletions.
90 changes: 67 additions & 23 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,33 +1,77 @@
name: Build

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

jobs:
dagger-build:
dagger-build-satellite:
runs-on: ubuntu-latest
permissions:
contents: write
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Build the binary for the satellite
uses: dagger/dagger-for-github@v5
with:
version: latest
verb: call
module: github.com/container-registry/harbor-satellite
args: build --source=. --name=satellite

- name: Release on Github
uses: dagger/dagger-for-github@v5
with:
version: latest
verb: call
module: github.com/container-registry/harbor-satellite
args: release --source=. --name=satellite --token=$GITHUB_TOKEN

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_USERNAME: ${{ github.repository_owner }}
GITHUB_SHA: ${{ github.sha }}
### Uncomment the below line if you wish to see the traces of the workflow on dagger cloud
### register to dagger cloud and get the token
#### https://dagger.cloud/
# cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}

build-ground-control:
runs-on: ubuntu-latest
# 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' }}
permissions:
contents: write
packages: write
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: Build the binary for ground control
uses: dagger/dagger-for-github@v5
with:
version: latest
verb: call
module: github.com/container-registry/harbor-satellite
args: build --source=./ground-control --name=ground-control

- name: Release on Github
uses: dagger/dagger-for-github@v5
with:
version: latest
verb: call
module: github.com/container-registry/harbor-satellite
args: release --source=. --name=ground-control --token=$GITHUB_TOKEN

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_USERNAME: ${{ github.repository_owner }}
GITHUB_SHA: ${{ github.sha }}
### Uncomment the below line if you wish to see the traces of the workflow on dagger cloud
### register to dagger cloud and get the token
#### https://dagger.cloud/
# cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ go.work
dist/

# Remove DS_Store
.DS_Store
.DS_Store
zot/cache.db
secrets.txt
59 changes: 59 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com

# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

version: 2
project_name: harbor-satellite

git:
ignore_tags:
- "*-ground-control"
builds:
- main: "./main.go"
binary: "{{ .Env.APP_NAME }}"
env:
- CGO_ENABLED=0
ldflags:
- -w -s -X github.com/container-registry/harbor-satellite/internal/version.GitCommit={{.FullCommit}}
goos:
- linux
- darwin
goarch:
- amd64
- arm64
ignore:
- goos: windows
goarch: arm
- goos: windows
goarch: arm64
mod_timestamp: "{{ .CommitTimestamp }}"


release:
name_template: "{{ .Tag }}"

archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .Env.APP_NAME }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
format: zip

changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
4 changes: 4 additions & 0 deletions ci/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/dagger.gen.go linguist-generated
/internal/dagger/** linguist-generated
/internal/querybuilder/** linguist-generated
/internal/telemetry/** linguist-generated
4 changes: 4 additions & 0 deletions ci/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/dagger.gen.go
/internal/dagger
/internal/querybuilder
/internal/telemetry
74 changes: 74 additions & 0 deletions ci/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Harbor Satellite CI/CD Pipeline

This repository uses [Dagger](https://docs.dagger.io/) for testing, building, and releasing Harbor Satellite.

## Setting Up Dagger for Harbor Satellite

Follow the steps below to set up Dagger:

### 1. Install Dagger CLI

Choose your operating system and install the Dagger CLI:

- **macOS:**
```sh
brew install dagger/tap/dagger
- **Windows:**
```sh
Invoke-WebRequest -UseBasicParsing -Uri https://dl.dagger.io/dagger/install.ps1 | Invoke-Expression; Install-Dagger
- **Linux:**
```sh
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh

### 2. Verify Installation
Run the following command to verify the Dagger installation:
- ```sh
dagger --version
If you encounter any errors, refer to the [detailed installation guide](https://docs.dagger.io/install).
### 3. Generate Go Code
Once the Dagger CLI is installed, navigate to the root folder of harbor-satellite and run:
- ```sh
dagger develop

This command will generate Go code in the ./ci folder.

### 4. Folder Structure
After running dagger develop, your ./ci folder should contain the following structure:
- ```sh
ci/
├── dagger.gen.go
├── ground_control.go
├── internal
│ ├── dagger
│ ├── querybuilder
│ └── telemetry
├── satellite.go
├── README.md
├── release.sh
└── utils.go
If you encounter any issues during this process, consult the [Dagger Quickstart Guide](https://docs.dagger.io/quickstart/daggerize) for more detailed instructions.
## Running Dagger Functions
To view available functions, run:
- ```sh
dagger functions
To run a particular function, run:
- ```sh
dagger call <function_name> --args
- #### Example: Building Satellite Binaries
To build the satellite binaries, use the following command:
- ```sh
dagger call build --source=. --name=satellite export --path=./bin
This would spin up a container and install required dependencies and build various architecture binaries and export them to the host on path ./bin for testing on the host.
- #### Example: Releasing to GitHub
To release the project on GitHub, use the following command
- ```sh
dagger call release --directory=. --token=<your_github_token> --name=satellite
The above function would then proceed to release the project on github for the name provided. The above function also takes argument `--release-type` which would tell the release what kind of release it is i.e major, minor or path, The default value is set to be path release
- #### Example: Releasing to GitHub with type of release
To release the project on GitHub, use the following command
- ```sh
dagger call release --directory=. --token=<your_github_token> --name=satellite --release-type=minor
The above function would release the minor version for the project mentioned
36 changes: 36 additions & 0 deletions ci/ground_control.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"context"
"fmt"

"container-registry.com/harbor-satellite/ci/internal/dagger"
)

// Would execute the tests for the ground control. Source should be the path to the path to main.go file.
func (m *HarborSatellite) ExecuteTestsForGroundControl(ctx context.Context, source *dagger.Directory) (string, error) {
goContainer := dag.Container().
From(DEFAULT_GO)

containerWithDocker, err := m.Attach(ctx, goContainer, "24.0")
if err != nil {
return "", err
}
dockerHost, err := containerWithDocker.EnvVariable(ctx, "DOCKER_HOST")
if err != nil {
return "", err
}
fmt.Printf("Docker Host: %s\n", dockerHost)

goContainer = containerWithDocker.
WithMountedDirectory("/app", source).
WithWorkdir("/app").
WithExec([]string{"go", "test", "./..."})

output, err := goContainer.Stdout(ctx)
if err != nil {
return output, err
}
fmt.Print(output)
return output, nil
}
72 changes: 56 additions & 16 deletions ci/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,71 @@ package main

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

"dagger.io/dagger"
"container-registry.com/harbor-satellite/ci/internal/dagger"
)

func main() {
ctx := context.Background()
const (
DEFAULT_GO = "golang:1.22"
PROJ_MOUNT = "/app"
DOCKER_PORT = 2375
GORELEASER_VERSION = "v2.1.0"
GROUND_CONTROL_PATH = "./ground-control"
SATELLITE_PATH = "."
)

type HarborSatellite struct{}

// Build function would start the build process for the name provided. Source should be the path to the main.go file.
func (m *HarborSatellite) Build(ctx context.Context, source *dagger.Directory, name string) *dagger.Directory {
return m.build(source, name)
}

// Release function would release the build to the github with the tags provided. Directory should be "." for both the satellite and the ground control.
func (m *HarborSatellite) Release(ctx context.Context, directory *dagger.Directory, token, name string,
// +optional
// +default="patch"
release_type string) (string, error) {

// initialize Dagger client
client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stderr))
container := dag.Container().
From("alpine/git").
WithEnvVariable("GITHUB_TOKEN", token).
WithMountedDirectory(PROJ_MOUNT, directory).
WithWorkdir(PROJ_MOUNT).
WithExec([]string{"git", "config", "--global", "url.https://github.com/.insteadOf", "git@github.com:"}).
WithExec([]string{"git", "fetch", "--tags"})
// Prepare the tags for the release
release_tag, err := m.get_release_tag(ctx, container, directory, name, release_type)
if err != nil {
panic(err)
slog.Error("Failed to prepare for release: ", err, ".")
slog.Error("Tag Release Output:", release_tag, ".")
os.Exit(1)
}
defer client.Close()

// use a golang:1.19 container
// get version
// execute
golang := client.Container().From("golang:1.21").WithExec([]string{"go", "version"})
slog.Info("Tag Release Output:", release_tag, ".")
pathToMain, err := m.getPathToReleaser(name)
if err != nil {
slog.Error("Failed to get path to main: ", err, ".")
os.Exit(1)
}
release_output, err := container.
From(fmt.Sprintf("goreleaser/goreleaser:%s", GORELEASER_VERSION)).
WithMountedDirectory(PROJ_MOUNT, directory).
WithWorkdir(PROJ_MOUNT).
WithEnvVariable("GITHUB_TOKEN", token).
WithEnvVariable("PATH_TO_MAIN", pathToMain).
WithEnvVariable("APP_NAME", name).
WithExec([]string{"git", "tag", release_tag}).
WithExec([]string{"goreleaser", "release", "-f", pathToMain, "--clean"}).
Stderr(ctx)

version, err := golang.Stdout(ctx)
if err != nil {
panic(err)
slog.Error("Failed to release: ", err, ".")
slog.Error("Release Output:", release_output, ".")
os.Exit(1)
}
// print output
slog.Info("Hello from Dagger!", "version", version)

return release_output, nil
}
Loading

0 comments on commit 02ba374

Please sign in to comment.