Skip to content

Commit 9937990

Browse files
committed
feat: Adding Publish and Sign of image as an independent component
Signed-off-by: NucleoFusion <[email protected]> test: testing with fork Signed-off-by: NucleoFusion <[email protected]> fix: omitted publish Signed-off-by: NucleoFusion <[email protected]> fix: args mismatch Signed-off-by: NucleoFusion <[email protected]> fix: invalid checkout Signed-off-by: NucleoFusion <[email protected]> fix: nil pointer error Signed-off-by: NucleoFusion <[email protected]> fix: addressing error Signed-off-by: NucleoFusion <[email protected]> fix: goVersion error Signed-off-by: NucleoFusion <[email protected]> fix: image addresses error Signed-off-by: NucleoFusion <[email protected]> fix: nil pointer error Signed-off-by: NucleoFusion <[email protected]> fix: nil pointer error Signed-off-by: NucleoFusion <[email protected]> fix: nil pointer error Signed-off-by: NucleoFusion <[email protected]> fix: debug params Signed-off-by: NucleoFusion <[email protected]> fix: debug params Signed-off-by: NucleoFusion <[email protected]> fix: debug params Signed-off-by: NucleoFusion <[email protected]> fix: debug params Signed-off-by: NucleoFusion <[email protected]> fix: debug params Signed-off-by: NucleoFusion <[email protected]>
1 parent dfc38c9 commit 9937990

File tree

7 files changed

+196
-47
lines changed

7 files changed

+196
-47
lines changed

.dagger/image/build.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package image
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"dagger/harbor-cli/internal/dagger"
9+
"dagger/harbor-cli/utils"
10+
)
11+
12+
func (s *ImagePipeline) Build(ctx context.Context, dist *dagger.Directory) (*dagger.Directory, error) {
13+
goarch := []string{"amd64", "arm64"}
14+
15+
for _, arch := range goarch {
16+
// Defining binary file name
17+
binName := fmt.Sprintf("harbor-cli_%s_%s_%s", s.appVersion, "linux", arch)
18+
19+
builder := s.dag.Container().
20+
From("golang:"+s.goVersion).
21+
WithMountedCache("/go/pkg/mod", s.dag.CacheVolume("go-mod-"+s.goVersion)).
22+
WithEnvVariable("GOMODCACHE", "/go/pkg/mod").
23+
WithMountedCache("/go/build-cache", s.dag.CacheVolume("go-build-"+s.goVersion)).
24+
WithEnvVariable("GOCACHE", "/go/build-cache").
25+
WithMountedDirectory("/src", s.source).
26+
WithWorkdir("/src").
27+
WithEnvVariable("GOOS", "linux").
28+
WithEnvVariable("GOARCH", arch).
29+
WithEnvVariable("CGO_ENABLED", "0")
30+
31+
gitCommit, _ := builder.WithExec([]string{"git", "rev-parse", "--short", "HEAD", "--always"}).Stdout(ctx)
32+
buildTime := time.Now().UTC().Format(time.RFC3339)
33+
34+
ldflagsArgs := utils.LDFlags(ctx, s.appVersion, s.goVersion, buildTime, gitCommit)
35+
36+
builder = builder.WithExec([]string{
37+
"bash", "-c",
38+
fmt.Sprintf(`set -ex && go env && go build -v -ldflags "%s" -o /bin/%s /src/cmd/harbor/main.go`, ldflagsArgs, binName),
39+
})
40+
41+
file := builder.File("/bin/" + binName) // Taking file from container
42+
dist = dist.WithFile(fmt.Sprintf("%s/%s", "linux", binName), file) // Adding file(bin) to dist directory
43+
}
44+
45+
return dist, nil
46+
}

.dagger/image/imagepipeline.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package image
2+
3+
import "dagger/harbor-cli/internal/dagger"
4+
5+
type ImagePipeline struct {
6+
source *dagger.Directory
7+
dag *dagger.Client
8+
RegistryPassword *dagger.Secret
9+
GithubToken *dagger.Secret
10+
ActionsIDTokenRequestURL *dagger.Secret
11+
ActionsIDTokenRequestToken *dagger.Secret
12+
RegistryAddress string
13+
RegistryUsername string
14+
appVersion string
15+
goVersion string
16+
}
17+
18+
func InitImagePipeline(dag *dagger.Client, source *dagger.Directory,
19+
registryPassword, githubToken, actionsIDTokenRequestURL, actionsIDTokenRequestToken *dagger.Secret,
20+
registryAddress, registryUsername, appVersion, goVersion string,
21+
) *ImagePipeline {
22+
return &ImagePipeline{
23+
source: source,
24+
dag: dag,
25+
RegistryPassword: registryPassword,
26+
GithubToken: githubToken,
27+
RegistryAddress: registryAddress,
28+
RegistryUsername: registryUsername,
29+
ActionsIDTokenRequestURL: actionsIDTokenRequestURL,
30+
ActionsIDTokenRequestToken: actionsIDTokenRequestToken,
31+
appVersion: appVersion,
32+
goVersion: goVersion,
33+
}
34+
}
Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package pipeline
1+
package image
22

33
import (
44
"context"
@@ -10,23 +10,25 @@ import (
1010
)
1111

1212
// PublishImage publishes a container image to a registry with a specific tag and signs it using Cosign.
13-
func (s *Pipeline) PublishImage(
14-
ctx context.Context,
15-
dist *dagger.Directory,
16-
registry, registryUsername string,
17-
// +optional
18-
// +default=["latest"]
19-
imageTags []string,
20-
registryPassword *dagger.Secret,
21-
) []string {
13+
func (s *ImagePipeline) PublishImage(ctx context.Context, dist *dagger.Directory) []string {
2214
version := s.appVersion
2315
archs := []string{"amd64", "arm64"}
2416
releaseImages := []*dagger.Container{}
17+
imageTags := []string{s.appVersion, "latest"}
18+
19+
// Debug
20+
fmt.Println("RegistryAddress:", s.RegistryAddress)
21+
fmt.Println("RegistryUsername:", s.RegistryUsername)
22+
fmt.Println("AppVersion:", s.appVersion)
23+
fmt.Println("GoVersion:", s.goVersion)
24+
pw, _ := s.RegistryPassword.Plaintext(ctx)
25+
fmt.Println("Registry password len:", len(pw))
2526

2627
for i, tag := range imageTags {
2728
imageTags[i] = strings.TrimSpace(tag)
2829
imageTags[i] = strings.TrimPrefix(imageTags[i], "v")
2930
}
31+
3032
fmt.Printf("provided tags: %s\n", imageTags)
3133

3234
// Get current time for image creation timestamp
@@ -54,9 +56,10 @@ func (s *Pipeline) PublishImage(
5456

5557
imageAddrs := []string{}
5658
for _, imageTag := range imageTags {
57-
addr, err := s.dag.Container().WithRegistryAuth(registry, registryUsername, registryPassword).
59+
fmt.Printf("%s/%s/harbor-cli:%s \n", s.RegistryAddress, s.RegistryUsername, imageTag)
60+
addr, err := s.dag.Container().WithRegistryAuth(s.RegistryAddress, s.RegistryUsername, s.RegistryPassword).
5861
Publish(ctx,
59-
fmt.Sprintf("%s/%s/harbor-cli:%s", registry, registryUsername, imageTag),
62+
fmt.Sprintf("%s/%s/harbor-cli:%s", s.RegistryAddress, s.RegistryUsername, imageTag),
6063
dagger.ContainerPublishOpts{PlatformVariants: releaseImages},
6164
)
6265
if err != nil {
@@ -65,5 +68,6 @@ func (s *Pipeline) PublishImage(
6568
fmt.Printf("Published image address: %s\n", addr)
6669
imageAddrs = append(imageAddrs, addr)
6770
}
71+
6872
return imageAddrs
6973
}

.dagger/image/sign.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package image
2+
3+
import (
4+
"context"
5+
"fmt"
6+
)
7+
8+
func (s *ImagePipeline) Sign(ctx context.Context, imageAddr string) (string, error) {
9+
registryPasswordPlain, _ := s.RegistryPassword.Plaintext(ctx)
10+
11+
cosing_ctr := s.dag.Container().From("cgr.dev/chainguard/cosign")
12+
13+
// If githubToken is provided, use it to sign the image
14+
if s.GithubToken != nil {
15+
if s.ActionsIDTokenRequestURL == nil || s.ActionsIDTokenRequestToken == nil {
16+
return "", fmt.Errorf("actionsIdTokenRequestUrl (exist=%s) and actionsIdTokenRequestToken (exist=%t) must be provided when githubToken is provided",
17+
s.ActionsIDTokenRequestURL, s.ActionsIDTokenRequestToken != nil)
18+
}
19+
fmt.Printf("Setting the ENV Vars GITHUB_TOKEN, ACTIONS_ID_TOKEN_REQUEST_URL, ACTIONS_ID_TOKEN_REQUEST_TOKEN to sign with GitHub Token")
20+
cosing_ctr = cosing_ctr.WithSecretVariable("GITHUB_TOKEN", s.GithubToken).
21+
WithSecretVariable("ACTIONS_ID_TOKEN_REQUEST_URL", s.ActionsIDTokenRequestURL).
22+
WithSecretVariable("ACTIONS_ID_TOKEN_REQUEST_TOKEN", s.ActionsIDTokenRequestToken)
23+
}
24+
25+
return cosing_ctr.WithSecretVariable("REGISTRY_PASSWORD", s.RegistryPassword).
26+
WithExec([]string{"cosign", "env"}).
27+
WithExec([]string{
28+
"cosign", "sign", "--yes", "--recursive",
29+
"--registry-username", s.RegistryUsername,
30+
"--registry-password", registryPasswordPlain,
31+
imageAddr,
32+
"--timeout", "1m",
33+
}).Stdout(ctx)
34+
}

.dagger/main.go

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"regexp"
77
"strings"
88

9+
"dagger/harbor-cli/image"
910
"dagger/harbor-cli/internal/dagger"
1011
"dagger/harbor-cli/pipeline"
1112
)
@@ -21,8 +22,7 @@ type HarborCli struct {
2122
// -> Publishing to release page -> Publishing to apt
2223
func (m *HarborCli) Pipeline(ctx context.Context, source *dagger.Directory,
2324
// Secrets
24-
githubToken *dagger.Secret, registryPassword *dagger.Secret,
25-
registryAddr string, registryUsername string,
25+
githubToken *dagger.Secret,
2626
) (*dagger.Directory, error) {
2727
err := m.init(ctx, source)
2828
if err != nil {
@@ -63,20 +63,45 @@ func (m *HarborCli) Pipeline(ctx context.Context, source *dagger.Directory,
6363
}
6464
fmt.Println(out)
6565

66-
// Publishing Image
67-
res := pipe.PublishImage(ctx, dist, registryAddr, registryUsername, []string{"latest", m.AppVersion}, registryPassword)
66+
// // Publishing repo
67+
// err = pipe.AptRepoBuild(ctx, dist, githubToken)
68+
// if err != nil {
69+
// return nil, err
70+
// }
71+
72+
return dist, err
73+
}
74+
75+
func (m *HarborCli) PublishAndSignImage(ctx context.Context, source *dagger.Directory,
76+
registryPassword, githubToken, actionsIDTokenRequestURL, actionsIDTokenRequestToken *dagger.Secret,
77+
registryAddress, registryUsername string,
78+
) (*dagger.Directory, error) {
79+
err := m.init(ctx, source)
6880
if err != nil {
6981
return nil, err
7082
}
71-
fmt.Println(strings.Join(res, "\n"))
7283

73-
// Publishing repo
74-
err = pipe.AptRepoBuild(ctx, dist, githubToken)
84+
pipe := image.InitImagePipeline(dag, source, registryPassword, githubToken, actionsIDTokenRequestURL, actionsIDTokenRequestToken,
85+
registryAddress, registryUsername, m.AppVersion, m.GoVersion)
86+
87+
dist := dag.Directory()
88+
89+
// Building Binaries
90+
dist, err = pipe.Build(ctx, dist)
7591
if err != nil {
7692
return nil, err
7793
}
7894

79-
return dist, err
95+
// Publishing Image
96+
imageAddr := pipe.PublishImage(ctx, dist)
97+
98+
_, err = pipe.Sign(ctx, imageAddr[0])
99+
if err != nil {
100+
return nil, err
101+
}
102+
fmt.Println(strings.Join(imageAddr, "\n"))
103+
104+
return dist, nil
80105
}
81106

82107
func (m *HarborCli) init(ctx context.Context, source *dagger.Directory) error {
@@ -102,6 +127,10 @@ func (m *HarborCli) init(ctx context.Context, source *dagger.Directory) error {
102127
m.GoVersion = match[1]
103128
}
104129

130+
if m.GoVersion == "" {
131+
m.GoVersion = "latest"
132+
}
133+
105134
m.Source = source
106135
m.AppVersion = strings.TrimSpace(out)
107136

.github/actions/publish-and-sign/action.yaml

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,11 @@ name: Publish and Sign Snapshot Image
22
description: Publishes and signs a snapshot image using Dagger.
33

44
inputs:
5-
IMAGE_TAGS:
6-
description: 'Tags for the image, e.g. "latest, v1.0.0"'
7-
required: true
8-
GITHUB_TOKEN:
9-
description: 'GitHub token'
10-
required: true
11-
REGISTRY_PASSWORD:
12-
description: 'Registry password'
13-
required: true
145
REGISTRY_ADDRESS:
15-
description: 'Registry address'
6+
description: 'Registry address (e.g., ghcr.io)'
167
required: true
178
REGISTRY_USERNAME:
18-
description: 'Registry username'
9+
description: 'Registry username (e.g., nucleocode)'
1910
required: true
2011

2112
runs:
@@ -24,31 +15,30 @@ runs:
2415
- name: Dagger Version
2516
uses: sagikazarmark/[email protected]
2617

18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
2721
- name: Install Cosign
2822
uses: sigstore/[email protected]
2923

30-
- name: Check Env Variables
24+
- name: Debug OIDC Environment
3125
shell: bash
32-
env:
33-
GITHUB_TOKEN: ${{ inputs.GITHUB_TOKEN }}
34-
run: cosign env
26+
run: |
27+
echo $REGISTRY_PASSWORD
28+
echo "ACTIONS_ID_TOKEN_REQUEST_URL: $ACTIONS_ID_TOKEN_REQUEST_URL"
29+
echo "ACTIONS_ID_TOKEN_REQUEST_TOKEN present: $([[ -n \"$ACTIONS_ID_TOKEN_REQUEST_TOKEN\" ]] && echo yes || echo no)"
30+
cosign version
3531
36-
- name: Publish and Sign Snapshot Image
32+
- name: Publish and Sign Image
3733
uses: dagger/dagger-for-github@v7
3834
env:
3935
GITHUB_TOKEN: ${{ inputs.GITHUB_TOKEN }}
4036
REGISTRY_ADDRESS: ${{ inputs.REGISTRY_ADDRESS }}
4137
REGISTRY_USERNAME: ${{ inputs.REGISTRY_USERNAME }}
42-
REGISTRY_PASSWORD: ${{ inputs.REGISTRY_PASSWORD }}
43-
IMAGE_TAGS: ${{ inputs.IMAGE_TAGS }}
38+
REGISTRY_PASSWORD: ${{ env.REGISTRY_PASSWORD }}
39+
ACTIONS_ID_TOKEN_REQUEST_URL: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL }}
40+
ACTIONS_ID_TOKEN_REQUEST_TOKEN: ${{ env.ACTIONS_ID_TOKEN_REQUEST_TOKEN }}
4441
with:
4542
version: ${{ steps.dagger_version.outputs.version }}
4643
verb: call
47-
args: "publish-image-and-sign \
48-
--registry='${{ env.REGISTRY_ADDRESS }}' \
49-
--registry-username='${{ env.REGISTRY_USERNAME }}' \
50-
--registry-password=env:REGISTRY_PASSWORD \
51-
--image-tags='${{ env.IMAGE_TAGS}}' \
52-
--github-token=env:GITHUB_TOKEN \
53-
--actions-id-token-request-url=$ACTIONS_ID_TOKEN_REQUEST_URL \
54-
--actions-id-token-request-token=env:ACTIONS_ID_TOKEN_REQUEST_TOKEN"
44+
args: "publish-and-sign-image --source=. --registry-address=${{ inputs.REGISTRY_ADDRESS }} --registry-username=${{ inputs.REGISTRY_USERNAME }} --registry-password=env://REGISTRY_PASSWORD --github-token=env://GITHUB_TOKEN --actions-idtoken-request-url=env://ACTIONS_ID_TOKEN_REQUEST_URL --actions-idtoken-request-token=env://ACTIONS_ID_TOKEN_REQUEST_TOKEN"

.github/workflows/default.yaml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,4 +242,16 @@ jobs:
242242
version: "latest"
243243
verb: call
244244
# Using a single large line since, dagger parsing with folded/piped command fails due to improper formatting error
245-
args: pipeline --source=. --github-token=env://GITHUB_TOKEN --registry-password=env://REGISTRY_PASSWORD --registry-username=${{ vars.REGISTRY_USERNAME }} --registry-addr=${{ vars.REGISTRY_ADDRESS }}
245+
args: pipeline --source=. --github-token=env://GITHUB_TOKEN
246+
247+
- name: Publish and Sign Snapshot Image
248+
if: github.event_name == 'push' && (startsWith(github.ref, 'refs/tags/'))
249+
uses: ./.github/actions/publish-and-sign
250+
with:
251+
REGISTRY_ADDRESS: ${{ vars.REGISTRY_ADDRESS }}
252+
REGISTRY_USERNAME: ${{ vars.REGISTRY_USERNAME }}
253+
env:
254+
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
255+
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
256+
ACTIONS_ID_TOKEN_REQUEST_URL: ${{ env.ACTIONS_ID_TOKEN_REQUEST_URL }}
257+
ACTIONS_ID_TOKEN_REQUEST_TOKEN: ${{ env.ACTIONS_ID_TOKEN_REQUEST_TOKEN }}

0 commit comments

Comments
 (0)