Skip to content
This repository has been archived by the owner on Dec 17, 2024. It is now read-only.

Commit

Permalink
feat: all release and publish commands
Browse files Browse the repository at this point in the history
  • Loading branch information
flabatut committed Jan 26, 2024
1 parent 8c593f8 commit 0808c12
Show file tree
Hide file tree
Showing 12 changed files with 236 additions and 49 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
uses: dagger/[email protected]
with:
verb: run
args: --silent go run main.go publish artifact
args: --silent go run main.go publish all
env:
GITHUB_TOKEN: ${{ github.token }}

23 changes: 23 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@
"build"
]
},
{
"name": "release",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"args": [
"release",
],
"envFile": "${workspaceFolder}/.env",
},
{
"name": "publish image",
"type": "go",
Expand All @@ -47,6 +58,18 @@
"artifact"
],
"envFile": "${workspaceFolder}/.env",
},
{
"name": "publish all",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"args": [
"publish",
"all"
],
"envFile": "${workspaceFolder}/.env",
}
]
}
12 changes: 9 additions & 3 deletions cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,18 @@ func init() {
viper.SetDefault("builderNodeJSVersion", "latest") // vercel compatible format https://github.com/vercel/pkg
viper.SetDefault("runnerImage", "docker.io/debian:bullseye-slim") // same as Dockerfile FROM, image for final target container
viper.SetDefault("runnerEntryPointPath", "/entrypoint") // same as Dockerfile ENTRYPOINT
viper.SetDefault("releaseVersion", "v2024.1.0")
viper.SetDefault("registryFQDN", "ghcr.io") // TODO: revamp, remove publishaddress
viper.SetDefault("projectNamespace", "flabatut/bitwarden-cli") // TODO: make sure no / at the begining , discover value
viper.SetDefault("registryFQDN", "ghcr.io") // TODO: revamp, remove publishaddress
viper.SetDefault("projectNamespace", "flabatut/bitwarden-cli") // TODO: make sure no / at the begining , discover value
// viper.SetDefault("releaseVersion", "v2024.1.0")

err := markReleaseVersionRequired(buildCmd)
cobra.CheckErr(err)
}

func runBuildCmd(cmd *cobra.Command) ([]*dagger.Container, *dagger.Directory, error) {
if !viper.IsSet("releaseVersion") {
return nil, nil, fmt.Errorf("required flag(s) releaseVersion not set")
}
job := &build.Workflow{
Client: daggerClient,
ReleaseVersion: viper.GetString("releaseVersion"),
Expand Down
48 changes: 48 additions & 0 deletions cmd/publish_all.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"fmt"

// "github.com/flabatut/bitwarden-cli/pkg/publish/image"
// "github.com/flabatut/bitwarden-cli/pkg/publish/artifact"
"github.com/spf13/cobra"
// "github.com/spf13/viper"
)

// imageCmd represents the image command
var publishAllCmd = &cobra.Command{
Use: "all",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("publish all called")
if err := runPublishAllCmd(cmd); err != nil {
return err
}
return nil
},
}

func init() {
publishCmd.AddCommand(publishAllCmd)
err := markReleaseVersionRequired(publishAllCmd)
cobra.CheckErr(err)
}

func runPublishAllCmd(cmd *cobra.Command) error {
if err := runPublishArtifactCmd(cmd); err != nil {
return err
}
if err := runPublishImageCmd(cmd); err != nil {
return err
}
return nil
}
11 changes: 10 additions & 1 deletion cmd/publish_artifact.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ to quickly create a Cobra application.`,

func init() {
publishCmd.AddCommand(artifactCmd)
err := markReleaseVersionRequired(artifactCmd)
cobra.CheckErr(err)
}

func runPublishArtifactCmd(cmd *cobra.Command) error {
Expand All @@ -40,11 +42,18 @@ func runPublishArtifactCmd(cmd *cobra.Command) error {
return err
}

password, err := getRegistryPassword()
_, err = runReleaseCmd(cmd)
if err != nil {
return err
}

password, err := getRegistryPassword()
if err != nil {
return err
}
if !viper.IsSet("releaseVersion") {
return fmt.Errorf("required flag(s) releaseVersion not set")
}
job := &artifact.Workflow{
Client: daggerClient,
ReleaseVersion: viper.GetString("releaseVersion"),
Expand Down
16 changes: 5 additions & 11 deletions cmd/publish_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,8 @@ to quickly create a Cobra application.`,

func init() {
publishCmd.AddCommand(imageCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// imageCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// imageCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
err := markReleaseVersionRequired(imageCmd)
cobra.CheckErr(err)
}

func runPublishImageCmd(cmd *cobra.Command) error {
Expand All @@ -57,7 +49,9 @@ func runPublishImageCmd(cmd *cobra.Command) error {
if err != nil {
return err
}

if !viper.IsSet("releaseVersion") {
return fmt.Errorf("required flag(s) releaseVersion not set")
}
job := &image.Workflow{
Client: daggerClient,
ReleaseVersion: viper.GetString("releaseVersion"),
Expand Down
59 changes: 59 additions & 0 deletions cmd/release.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
"fmt"

"dagger.io/dagger"
"github.com/flabatut/bitwarden-cli/pkg/release"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// releaseCmd represents the release command
var releaseCmd = &cobra.Command{
Use: "release",
Short: "A brief description of your command",
Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("publish artifact called")
if _, err := runReleaseCmd(cmd); err != nil {
return err
}
return nil
},
}

func init() {
rootCmd.AddCommand(releaseCmd)
err := markReleaseVersionRequired(releaseCmd)
cobra.CheckErr(err)
}

func runReleaseCmd(cmd *cobra.Command) (*dagger.Container, error) {
fmt.Println("release called")
password, err := getRegistryPassword()
if err != nil {
return nil, err
}
w := &release.Workflow{
Client: daggerClient,
ProjectNamespace: viper.GetString("projectNamespace"),
RegistryPassword: password,
}
if !viper.IsSet("releaseVersion") {
return nil, fmt.Errorf("required flag(s) releaseVersion not set")
}
releaser, err := w.Release(cmd.Context(), viper.GetString("releaseVersion"))
if err != nil {
return nil, err
}
return releaser, nil
}
22 changes: 19 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import (
)

var (
cfgFile string
daggerClient *dagger.Client
platforms = []dagger.Platform{ // TODO: use viper with mapstruct
releaseVersion string
cfgFile string
daggerClient *dagger.Client
platforms = []dagger.Platform{ // TODO: use viper with mapstruct
"darwin/amd64", // a.k.a. x86_64
"darwin/arm64", // a.k.a. aarch64
"linux/amd64", // a.k.a. x86_64
Expand Down Expand Up @@ -122,3 +123,18 @@ func getRegistryPassword() (*dagger.Secret, error) {
}
return nil, fmt.Errorf("password for registry not found")
}

func markReleaseVersionRequired(cmd *cobra.Command) error {
cmd.Flags().StringVarP(&releaseVersion, "releaseVersion", "", "", "Release version(required)")

err := viper.BindPFlag("releaseVersion", cmd.Flags().Lookup("releaseVersion"))
if err != nil {
return err
}

err = viper.BindEnv("releaseVersion")
if err != nil {
return err
}
return nil
}
6 changes: 5 additions & 1 deletion pkg/build/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ func (w *Workflow) Build(ctx context.Context) ([]*dagger.Container, *dagger.Dire
// forge binary output path
distOutput := filepath.Join(containerDistDir, "bw-"+osName+"-"+archName)
// cross compile for platform
builder = builder.WithExec([]string{"npx", "pkg", ".", "--targets", targetPlatform, "--output", distOutput})
builder = builder.WithExec([]string{
"npx", "pkg", ".", "--targets", targetPlatform, "--output", distOutput,
}).WithExec([]string{
"bash", "-c", fmt.Sprintf("md5sum %s > %s.checksum", distOutput, distOutput),
})

// only build docker images for linux supported
if osName == "linux" {
Expand Down
8 changes: 0 additions & 8 deletions pkg/lint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,6 @@ type Workflow struct {

func (w *Workflow) Lint(ctx context.Context) error {

// fmt.Println("Linting with Dagger")
// var (
// zipFile = "cli-" + w.ReleaseVersion + ".zip"
// downloadUrl = "https://github.com/bitwarden/clients/archive/refs/tags/" + zipFile
// extractedZipDirName = "clients-cli-" + w.ReleaseVersion
// )
// docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.55.2 golangci-lint run -v

// get build context directory
contextDir := w.Client.Host().Directory(".")

Expand Down
29 changes: 8 additions & 21 deletions pkg/publish/artifact/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,12 @@ func (w *Workflow) Publish(ctx context.Context, artifacts *dagger.Directory) err

publisher := w.Client.Container().
From("alpine:latest").
WithMountedDirectory(containerDistDir, artifacts).
WithEnvVariable("GH_DEBUG", "api").
WithEnvVariable("GH_REPO", ghRepo).
WithSecretVariable("GH_TOKEN", w.RegistryPassword).
WithWorkdir(containerDistDir).
WithExec([]string{"apk", "add", "github-cli"})

_, err := publisher.WithExec([]string{
"gh", "release", "view", w.ReleaseVersion,
}).Stdout(ctx)
if err != nil {
if strings.HasSuffix(err.Error(), "release not found") {
_, err = publisher.WithExec([]string{
"gh", "release", "create", w.ReleaseVersion, "-t", w.ReleaseVersion, "--generate-notes",
}).Stdout(ctx)
if err != nil {
return err
}
} else {
return err
}
}
WithExec([]string{"apk", "add", "github-cli"}).
WithMountedDirectory(containerDistDir, artifacts).
// WithEnvVariable("GH_DEBUG", "api").
WithWorkdir(containerDistDir)

for _, platform := range w.PlatformsVariants {
// extract os/arch from platform
Expand All @@ -58,11 +42,14 @@ func (w *Workflow) Publish(ctx context.Context, artifacts *dagger.Directory) err
archName = strings.Split(string(platform), "/")[1]
)
binaryName := fmt.Sprintf("bw-%s-%s", osName, archName)
md5SumName := fmt.Sprintf("bw-%s-%s.checksum", osName, archName)
publisher = publisher.WithExec([]string{
"gh", "release", "upload", w.ReleaseVersion, binaryName, "--clobber",
}).WithExec([]string{
"gh", "release", "upload", w.ReleaseVersion, md5SumName, "--clobber",
})
}
_, err = publisher.Stdout(ctx)
_, err := publisher.Stdout(ctx)
if err != nil {
return err
}
Expand Down
49 changes: 49 additions & 0 deletions pkg/release/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package release

import (
"context"
"fmt"
"strings"
"time"

"dagger.io/dagger"
)

type Workflow struct {
Client *dagger.Client
ProjectNamespace string
RegistryPassword *dagger.Secret
}

func (w *Workflow) Release(ctx context.Context, releaseVersion string) (*dagger.Container, error) {
fmt.Println("Releasing with Dagger")

var ghRepo = fmt.Sprintf("github.com/%s", w.ProjectNamespace)

releaser := w.Client.Container().
From("alpine:latest").
// WithEnvVariable("GH_DEBUG", "api").
WithEnvVariable("GH_REPO", ghRepo).
WithSecretVariable("GH_TOKEN", w.RegistryPassword).
WithExec([]string{"apk", "add", "github-cli"})

// https://docs.dagger.io/cookbook/#invalidate-cache
_, err := releaser.WithEnvVariable("CACHEBUSTER", time.Now().String()).
WithExec([]string{
"gh", "release", "view", releaseVersion,
}).Stdout(ctx)
if err != nil {
if strings.HasSuffix(err.Error(), "release not found") {
_, err = releaser.WithEnvVariable("CACHEBUSTER", time.Now().String()).
WithExec([]string{
"gh", "release", "create", releaseVersion, "-t", releaseVersion, "--generate-notes",
}).Stdout(ctx)
if err != nil {
return nil, err
}
} else {
return nil, err
}
}
return releaser, nil
}

0 comments on commit 0808c12

Please sign in to comment.