From 8bf65129053e1a674bbba77b323077cce4df5e81 Mon Sep 17 00:00:00 2001 From: rmvangun <85766511+rmvangun@users.noreply.github.com> Date: Thu, 8 May 2025 20:46:11 -0400 Subject: [PATCH 01/14] Include a context ID (#1121) --- api/v1alpha1/config_types.go | 5 ++ api/v1alpha1/config_types_test.go | 16 +++++ pkg/config/config_handler.go | 1 + pkg/config/mock_config_handler.go | 9 +++ pkg/config/mock_config_handler_test.go | 30 +++++++++ pkg/config/shims.go | 39 ++++++------ pkg/config/yaml_config_handler.go | 20 ++++++ pkg/config/yaml_config_handler_test.go | 84 +++++++++++++++++++++++++- pkg/controller/controller.go | 6 ++ pkg/controller/controller_test.go | 54 +++++++++++++++++ pkg/env/terraform_env.go | 2 + pkg/env/terraform_env_test.go | 1 + 12 files changed, 248 insertions(+), 19 deletions(-) diff --git a/api/v1alpha1/config_types.go b/api/v1alpha1/config_types.go index 8b8527984..cc5bae23b 100644 --- a/api/v1alpha1/config_types.go +++ b/api/v1alpha1/config_types.go @@ -21,6 +21,7 @@ type Config struct { // Context represents the context configuration type Context struct { + ID *string `yaml:"id,omitempty"` ProjectName *string `yaml:"projectName,omitempty"` Blueprint *string `yaml:"blueprint,omitempty"` Environment map[string]string `yaml:"environment,omitempty"` @@ -40,6 +41,9 @@ func (base *Context) Merge(overlay *Context) { if overlay == nil { return } + if overlay.ID != nil { + base.ID = overlay.ID + } if overlay.ProjectName != nil { base.ProjectName = overlay.ProjectName } @@ -123,6 +127,7 @@ func (c *Context) DeepCopy() *Context { } } return &Context{ + ID: c.ID, ProjectName: c.ProjectName, Blueprint: c.Blueprint, Environment: environmentCopy, diff --git a/api/v1alpha1/config_types_test.go b/api/v1alpha1/config_types_test.go index 2be498b92..b2c91b92f 100644 --- a/api/v1alpha1/config_types_test.go +++ b/api/v1alpha1/config_types_test.go @@ -309,6 +309,22 @@ func TestConfig_Merge(t *testing.T) { t.Errorf("ProjectName mismatch: expected 'OverlayProject', got '%s'", *base.ProjectName) } }) + + t.Run("MergeWithID", func(t *testing.T) { + base := &Context{ + ID: ptrString("base-id"), + } + + overlay := &Context{ + ID: ptrString("overlay-id"), + } + + base.Merge(overlay) + + if base.ID == nil || *base.ID != "overlay-id" { + t.Errorf("ID mismatch: expected 'overlay-id', got '%s'", *base.ID) + } + }) } func TestConfig_Copy(t *testing.T) { diff --git a/pkg/config/config_handler.go b/pkg/config/config_handler.go index d9cac2536..60ea7ece5 100644 --- a/pkg/config/config_handler.go +++ b/pkg/config/config_handler.go @@ -38,6 +38,7 @@ type ConfigHandler interface { Clean() error IsLoaded() bool SetSecretsProvider(provider secrets.SecretsProvider) + GenerateContextID() error } const ( diff --git a/pkg/config/mock_config_handler.go b/pkg/config/mock_config_handler.go index 65eb30ab2..9311424b0 100644 --- a/pkg/config/mock_config_handler.go +++ b/pkg/config/mock_config_handler.go @@ -27,6 +27,7 @@ type MockConfigHandler struct { GetConfigRootFunc func() (string, error) CleanFunc func() error SetSecretsProviderFunc func(provider secrets.SecretsProvider) + GenerateContextIDFunc func() error } // ============================================================================= @@ -216,5 +217,13 @@ func (m *MockConfigHandler) SetSecretsProvider(provider secrets.SecretsProvider) } } +// GenerateContextID calls the mock GenerateContextIDFunc if set, otherwise returns nil +func (m *MockConfigHandler) GenerateContextID() error { + if m.GenerateContextIDFunc != nil { + return m.GenerateContextIDFunc() + } + return nil +} + // Ensure MockConfigHandler implements ConfigHandler var _ ConfigHandler = (*MockConfigHandler)(nil) diff --git a/pkg/config/mock_config_handler_test.go b/pkg/config/mock_config_handler_test.go index a098fa2cd..323f6dda8 100644 --- a/pkg/config/mock_config_handler_test.go +++ b/pkg/config/mock_config_handler_test.go @@ -705,3 +705,33 @@ func TestMockConfigHandler_SetSecretsProvider(t *testing.T) { handler.SetSecretsProvider(mockProvider) }) } + +func TestMockConfigHandler_GenerateContextID(t *testing.T) { + t.Run("WithMockFunction", func(t *testing.T) { + // Given a mock config handler with GenerateContextIDFunc set + handler := NewMockConfigHandler() + mockErr := fmt.Errorf("mock generate context ID error") + handler.GenerateContextIDFunc = func() error { return mockErr } + + // When GenerateContextID is called + err := handler.GenerateContextID() + + // Then the error should match the expected mock error + if err != mockErr { + t.Errorf("Expected error = %v, got = %v", mockErr, err) + } + }) + + t.Run("WithNoFuncSet", func(t *testing.T) { + // Given a mock config handler without GenerateContextIDFunc set + handler := NewMockConfigHandler() + + // When GenerateContextID is called + err := handler.GenerateContextID() + + // Then no error should be returned + if err != nil { + t.Errorf("Expected error = %v, got = %v", nil, err) + } + }) +} diff --git a/pkg/config/shims.go b/pkg/config/shims.go index 51c874d79..4ccb6ea17 100644 --- a/pkg/config/shims.go +++ b/pkg/config/shims.go @@ -1,6 +1,7 @@ package config import ( + "crypto/rand" "os" "github.com/goccy/go-yaml" @@ -12,29 +13,31 @@ import ( // Shims provides mockable wrappers around system and runtime functions type Shims struct { - ReadFile func(string) ([]byte, error) - WriteFile func(string, []byte, os.FileMode) error - RemoveAll func(string) error - Getenv func(string) string - Setenv func(string, string) error - Stat func(string) (os.FileInfo, error) - MkdirAll func(string, os.FileMode) error - YamlMarshal func(any) ([]byte, error) - YamlUnmarshal func([]byte, any) error + ReadFile func(string) ([]byte, error) + WriteFile func(string, []byte, os.FileMode) error + RemoveAll func(string) error + Getenv func(string) string + Setenv func(string, string) error + Stat func(string) (os.FileInfo, error) + MkdirAll func(string, os.FileMode) error + YamlMarshal func(any) ([]byte, error) + YamlUnmarshal func([]byte, any) error + CryptoRandRead func([]byte) (int, error) } // NewShims creates a new Shims instance with default implementations func NewShims() *Shims { return &Shims{ - ReadFile: os.ReadFile, - WriteFile: os.WriteFile, - RemoveAll: os.RemoveAll, - Getenv: os.Getenv, - Setenv: os.Setenv, - Stat: os.Stat, - MkdirAll: os.MkdirAll, - YamlMarshal: yaml.Marshal, - YamlUnmarshal: yaml.Unmarshal, + ReadFile: os.ReadFile, + WriteFile: os.WriteFile, + RemoveAll: os.RemoveAll, + Getenv: os.Getenv, + Setenv: os.Setenv, + Stat: os.Stat, + MkdirAll: os.MkdirAll, + YamlMarshal: yaml.Marshal, + YamlUnmarshal: yaml.Unmarshal, + CryptoRandRead: func(b []byte) (int, error) { return rand.Read(b) }, } } diff --git a/pkg/config/yaml_config_handler.go b/pkg/config/yaml_config_handler.go index d0e1fd0b2..f2b1932dd 100644 --- a/pkg/config/yaml_config_handler.go +++ b/pkg/config/yaml_config_handler.go @@ -645,3 +645,23 @@ func convertValue(value string, targetType reflect.Type) (any, error) { return convertedValue, nil } + +// GenerateContextID generates a random context ID if one doesn't exist +func (y *YamlConfigHandler) GenerateContextID() error { + if y.GetString("id") != "" { + return nil + } + + const charset = "abcdefghijklmnopqrstuvwxyz0123456789" + b := make([]byte, 7) + if _, err := y.shims.CryptoRandRead(b); err != nil { + return fmt.Errorf("failed to generate random context ID: %w", err) + } + + for i := range b { + b[i] = charset[int(b[i])%len(charset)] + } + + id := "w" + string(b) + return y.SetContextValue("id", id) +} diff --git a/pkg/config/yaml_config_handler_test.go b/pkg/config/yaml_config_handler_test.go index ac2da447a..754004578 100644 --- a/pkg/config/yaml_config_handler_test.go +++ b/pkg/config/yaml_config_handler_test.go @@ -1650,6 +1650,7 @@ func TestYamlConfigHandler_SetContextValue(t *testing.T) { t.Fatalf("Failed to initialize handler: %v", err) } handler.shims = mocks.Shims + handler.path = filepath.Join(t.TempDir(), "config.yaml") return handler, mocks } @@ -1991,7 +1992,6 @@ func TestYamlConfigHandler_ConvertValue(t *testing.T) { // When converting the value _, err := convertValue(value, targetType) - // Then an error should be returned if err == nil { t.Fatal("Expected error for integer overflow") @@ -2397,3 +2397,85 @@ func Test_setValueByPath(t *testing.T) { } }) } + +func TestYamlConfigHandler_GenerateContextID(t *testing.T) { + setup := func(t *testing.T) (*YamlConfigHandler, *Mocks) { + mocks := setupMocks(t) + handler := NewYamlConfigHandler(mocks.Injector) + handler.shims = mocks.Shims + if err := handler.Initialize(); err != nil { + t.Fatalf("Failed to initialize handler: %v", err) + } + return handler, mocks + } + + t.Run("WhenContextIDExists", func(t *testing.T) { + // Given a set of safe mocks and a YamlConfigHandler + handler, _ := setup(t) + + // And an existing context ID + existingID := "w1234567" + handler.SetContextValue("id", existingID) + + // When GenerateContextID is called + err := handler.GenerateContextID() + + // Then no error should be returned + if err != nil { + t.Fatalf("GenerateContextID() unexpected error: %v", err) + } + + // And the existing ID should remain unchanged + if got := handler.GetString("id"); got != existingID { + t.Errorf("Expected ID = %v, got = %v", existingID, got) + } + }) + + t.Run("WhenContextIDDoesNotExist", func(t *testing.T) { + // Given a set of safe mocks and a YamlConfigHandler + handler, _ := setup(t) + + // When GenerateContextID is called + err := handler.GenerateContextID() + + // Then no error should be returned + if err != nil { + t.Fatalf("GenerateContextID() unexpected error: %v", err) + } + + // And a new ID should be generated + id := handler.GetString("id") + if id == "" { + t.Fatal("Expected non-empty ID") + } + + // And the ID should start with 'w' and be 8 characters long + if len(id) != 8 || !strings.HasPrefix(id, "w") { + t.Errorf("Expected ID to start with 'w' and be 8 characters long, got: %s", id) + } + }) + + t.Run("WhenRandomGenerationFails", func(t *testing.T) { + // Given a set of safe mocks and a YamlConfigHandler + handler, _ := setup(t) + + // And a mocked crypto/rand that fails + handler.shims.CryptoRandRead = func([]byte) (int, error) { + return 0, fmt.Errorf("mocked crypto/rand error") + } + + // When GenerateContextID is called + err := handler.GenerateContextID() + + // Then an error should be returned + if err == nil { + t.Fatal("Expected error, got nil") + } + + // And the error message should be as expected + expectedError := "failed to generate random context ID: mocked crypto/rand error" + if err.Error() != expectedError { + t.Errorf("Expected error = %v, got = %v", expectedError, err) + } + }) +} diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index e00ef4fae..bc3a2e83e 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -411,6 +411,7 @@ func (c *BaseController) InitializeWithRequirements(req Requirements) error { if err := c.CreateComponents(); err != nil { return fmt.Errorf("failed to create components: %w", err) } + if err := c.InitializeComponents(); err != nil { return fmt.Errorf("failed to initialize components: %w", err) } @@ -748,6 +749,11 @@ func (c *BaseController) createConfigComponent(req Requirements) error { return nil } + // Generate context ID + if err := configHandler.GenerateContextID(); err != nil { + return fmt.Errorf("failed to generate context ID: %w", err) + } + return nil } diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index dcbe1f2e2..46399e388 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -2285,6 +2285,60 @@ func TestBaseController_createConfigComponent(t *testing.T) { t.Errorf("Expected no error, got %v", err) } }) + + t.Run("GeneratesContextID", func(t *testing.T) { + // Given a controller with a config handler + controller, mocks := setup(t) + mockConfigHandler := config.NewMockConfigHandler() + var generateCalled bool + mockConfigHandler.GenerateContextIDFunc = func() error { + generateCalled = true + return nil + } + controller.constructors.NewConfigHandler = func(di.Injector) config.ConfigHandler { + return mockConfigHandler + } + + // Clear any existing config handler + mocks.Injector.Register("configHandler", nil) + + // When creating the config component + err := controller.createConfigComponent(Requirements{}) + + // Then context ID should be generated + if err != nil { + t.Errorf("Expected no error, got: %v", err) + } + if !generateCalled { + t.Error("Expected GenerateContextID to be called") + } + }) + + t.Run("HandlesGenerateContextIDError", func(t *testing.T) { + // Given a controller with a failing config handler + controller, mocks := setup(t) + mockConfigHandler := config.NewMockConfigHandler() + mockConfigHandler.GenerateContextIDFunc = func() error { + return fmt.Errorf("failed to generate context ID") + } + controller.constructors.NewConfigHandler = func(di.Injector) config.ConfigHandler { + return mockConfigHandler + } + + // Clear any existing config handler + mocks.Injector.Register("configHandler", nil) + + // When creating the config component + err := controller.createConfigComponent(Requirements{}) + + // Then the error should be propagated + if err == nil { + t.Error("Expected error, got nil") + } + if !strings.Contains(err.Error(), "failed to generate context ID") { + t.Errorf("Expected error about context ID generation, got: %v", err) + } + }) } func TestBaseController_createSecretsComponents(t *testing.T) { diff --git a/pkg/env/terraform_env.go b/pkg/env/terraform_env.go index bd6b77094..f61e549fc 100644 --- a/pkg/env/terraform_env.go +++ b/pkg/env/terraform_env.go @@ -67,6 +67,7 @@ func (e *TerraformEnvPrinter) GetEnvVars() (map[string]string, error) { "TF_CLI_ARGS_import", "TF_CLI_ARGS_destroy", "TF_VAR_context_path", + "TF_VAR_context_id", "TF_VAR_os_type", } @@ -119,6 +120,7 @@ func (e *TerraformEnvPrinter) GetEnvVars() (map[string]string, error) { envVars["TF_CLI_ARGS_import"] = strings.TrimSpace(strings.Join(varFileArgs, " ")) envVars["TF_CLI_ARGS_destroy"] = strings.TrimSpace(strings.Join(varFileArgs, " ")) envVars["TF_VAR_context_path"] = strings.TrimSpace(filepath.ToSlash(configRoot)) + envVars["TF_VAR_context_id"] = strings.TrimSpace(e.configHandler.GetString("id", "")) // Set os_type based on the OS if e.shims.Goos() == "windows" { diff --git a/pkg/env/terraform_env_test.go b/pkg/env/terraform_env_test.go index 58bdd8f2d..c8e5d4fc4 100644 --- a/pkg/env/terraform_env_test.go +++ b/pkg/env/terraform_env_test.go @@ -486,6 +486,7 @@ func TestTerraformEnv_Print(t *testing.T) { filepath.Join(configRoot, "terraform/project/path.tfvars"), filepath.Join(configRoot, "terraform/project/path.tfvars.json")), "TF_VAR_context_path": configRoot, + "TF_VAR_context_id": "", "TF_VAR_os_type": expectedOSType, } From 601047b26ce2d6d0f6d9ed048eac159790ecd899 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 21:37:11 -0400 Subject: [PATCH 02/14] Try first chocolatey publish --- .github/workflows/ci.yaml | 13 +++++++-- .goreleaser.yaml | 58 ++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6c82b7b5f..316fa29dc 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -149,14 +149,23 @@ jobs: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.GPG_PASSPHRASE }} + - name: Check if prerelease + id: prerelease + run: | + if [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+- ]]; then + echo "prerelease=true" >> $GITHUB_OUTPUT + else + echo "prerelease=false" >> $GITHUB_OUTPUT + fi + - name: Run GoReleaser uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 with: version: "~> v2" - args: release --clean + args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GPG_FINGERPRINT: ${{ env.GPG_FINGERPRINT }} HOMEBREW_CLI_WRITE_PAT: ${{ secrets.HOMEBREW_CLI_WRITE_PAT }} + CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }} GITHUB_SHA: ${{ github.sha }} - SKIP_HOMEBREW: ${{ steps.prerelease.outputs.prerelease == 'true' }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 4bc428f6e..9b72776da 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -15,11 +15,11 @@ builds: - CGO_ENABLED=0 main: ./cmd/windsor goos: - - darwin - - linux + # - darwin + # - linux - windows goarch: - - arm64 + # - arm64 - amd64 ldflags: - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.version={{ .Version }}'" @@ -59,16 +59,48 @@ binary_signs: signs: - artifacts: checksum -brews: +# brews: +# - name: windsor +# directory: Formula +# repository: +# owner: windsorcli +# name: homebrew-cli +# branch: main +# token: "{{ .Env.HOMEBREW_CLI_WRITE_PAT }}" +# homepage: "https://windsorcli.github.io" +# description: "The Windsor Command Line Interface" +# ids: +# - windsor + +chocolateys: - name: windsor - directory: Formula - skip_upload: "{{ eq .Env.SKIP_HOMEBREW \"true\" }}" - repository: - owner: windsorcli - name: homebrew-cli - branch: main - token: "{{ .Env.HOMEBREW_CLI_WRITE_PAT }}" - homepage: "https://windsorcli.github.io" - description: "The Windsor Command Line Interface" ids: - windsor + package_source_url: https://github.com/windsorcli/cli + owners: Windsor CLI + title: Windsor CLI + authors: Windsor CLI Team + project_url: https://windsorcli.github.io + # icon_url: https://windsorcli.github.io/icon.png + copyright: "{{ .Year }} Windsor CLI Team" + license_url: https://github.com/windsorcli/cli/blob/main/LICENSE + require_license_acceptance: false + project_source_url: https://github.com/windsorcli/cli + docs_url: https://windsorcli.github.io + bug_tracker_url: https://github.com/windsorcli/cli/issues + tags: "cli windows command-line" + summary: "The Windsor Command Line Interface" + description: | + The Windsor CLI assists your cloud native development workflow. + This package provides the Windows installer for Windsor CLI. + + After installation, add the following line to your PowerShell profile to enable shell integration: + ```powershell + Invoke-Expression (& windsor hook powershell) + ``` + + Your PowerShell profile is located at: $PROFILE + release_notes: "https://github.com/windsorcli/cli/releases/tag/v{{ .Version }}" + skip_publish: false + api_key: "{{ .Env.CHOCOLATEY_API_KEY }}" + source_repo: "https://push.chocolatey.org/" From 39bc6a921f7fc364f380cd8b7962fe890634962b Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 21:42:11 -0400 Subject: [PATCH 03/14] Just run chocolatey --- .github/workflows/ci.yaml | 184 +++++++++++++++++++------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 316fa29dc..9fed530c8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,106 +13,106 @@ permissions: issues: read pull-requests: read jobs: - build-and-test: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - arch: [amd64, arm64] - exclude: - - os: windows-latest - arch: arm64 - runs-on: ${{ matrix.os }} - - steps: - - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install Aqua - uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 - with: - aqua_version: v2.51.1 - - - name: Install tools - run: aqua install - - - name: Cache Go Modules - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + # build-and-test: + # strategy: + # matrix: + # os: [ubuntu-latest, windows-latest, macos-latest] + # arch: [amd64, arm64] + # exclude: + # - os: windows-latest + # arch: arm64 + # runs-on: ${{ matrix.os }} + + # steps: + # - name: Checkout code + # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # - name: Install Aqua + # uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 + # with: + # aqua_version: v2.51.1 + + # - name: Install tools + # run: aqua install + + # - name: Cache Go Modules + # uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + # with: + # path: | + # ~/.cache/go-build + # ~/go/pkg/mod + # key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + # restore-keys: | + # ${{ runner.os }}-go- - - name: Install Dependencies - run: go install ./... + # - name: Install Dependencies + # run: go install ./... - - name: Run tests - run: task test - - - name: Test Build Windsor CLI on macOS/Linux - if: ${{ matrix.os != 'windows-latest' }} - run: | - VERSION=$(echo "${GITHUB_REF}" | sed 's/refs\/heads\///' | sed 's/refs\/tags\///') - echo "Testing build for version: $VERSION" - COMMIT_SHA=${{ github.sha }} - if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then - GOOS=linux GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go - elif [ "${{ matrix.os }}" == "macos-latest" ]; then - GOOS=darwin GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go - fi - - - name: Test Build Windsor CLI on Windows - if: ${{ matrix.os == 'windows-latest' }} - run: | - $env:VERSION = $env:GITHUB_REF -replace 'refs/heads/', '' -replace 'refs/tags/', '' - echo "Testing build for version: $env:VERSION" - $env:COMMIT_SHA = "${{ github.sha }}" - $env:GOOS = "windows" - $env:GOARCH = "${{ matrix.arch }}" - go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$env:VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$env:COMMIT_SHA'" -o NUL cmd\windsor\main.go - shell: pwsh - - sast-scan: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Install Aqua - uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 - with: - aqua_version: v2.51.1 - - - name: Install tools - run: aqua install - - - name: Cache Go Modules - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + # - name: Run tests + # run: task test + + # - name: Test Build Windsor CLI on macOS/Linux + # if: ${{ matrix.os != 'windows-latest' }} + # run: | + # VERSION=$(echo "${GITHUB_REF}" | sed 's/refs\/heads\///' | sed 's/refs\/tags\///') + # echo "Testing build for version: $VERSION" + # COMMIT_SHA=${{ github.sha }} + # if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then + # GOOS=linux GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go + # elif [ "${{ matrix.os }}" == "macos-latest" ]; then + # GOOS=darwin GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go + # fi + + # - name: Test Build Windsor CLI on Windows + # if: ${{ matrix.os == 'windows-latest' }} + # run: | + # $env:VERSION = $env:GITHUB_REF -replace 'refs/heads/', '' -replace 'refs/tags/', '' + # echo "Testing build for version: $env:VERSION" + # $env:COMMIT_SHA = "${{ github.sha }}" + # $env:GOOS = "windows" + # $env:GOARCH = "${{ matrix.arch }}" + # go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$env:VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$env:COMMIT_SHA'" -o NUL cmd\windsor\main.go + # shell: pwsh + + # sast-scan: + # runs-on: ubuntu-latest + # steps: + # - name: Checkout code + # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # - name: Install Aqua + # uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 + # with: + # aqua_version: v2.51.1 + + # - name: Install tools + # run: aqua install + + # - name: Cache Go Modules + # uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + # with: + # path: | + # ~/.cache/go-build + # ~/go/pkg/mod + # key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + # restore-keys: | + # ${{ runner.os }}-go- - - name: Install Dependencies - run: go install ./... + # - name: Install Dependencies + # run: go install ./... - - name: Run Gosec Security Scanner - uses: securego/gosec@955a68d0d19f4afb7503068f95059f7d0c529017 # v2.22.3 - with: - args: ./... - env: - GOTOOLCHAIN: 'local' - GOFLAGS: '-buildvcs=false' + # - name: Run Gosec Security Scanner + # uses: securego/gosec@955a68d0d19f4afb7503068f95059f7d0c529017 # v2.22.3 + # with: + # args: ./... + # env: + # GOTOOLCHAIN: 'local' + # GOFLAGS: '-buildvcs=false' release: runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/') - needs: [build-and-test, sast-scan] + # needs: [build-and-test, sast-scan] steps: - name: Checkout code From 07aa53acaf0ba2edd10512e9c5c98e04442f1405 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 21:46:46 -0400 Subject: [PATCH 04/14] Set year --- .goreleaser.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 9b72776da..7b9d0807a 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -81,8 +81,8 @@ chocolateys: title: Windsor CLI authors: Windsor CLI Team project_url: https://windsorcli.github.io - # icon_url: https://windsorcli.github.io/icon.png - copyright: "{{ .Year }} Windsor CLI Team" + icon_url: https://windsorcli.github.io/icon.png + copyright: "2025 Windsor CLI Team" license_url: https://github.com/windsorcli/cli/blob/main/LICENSE require_license_acceptance: false project_source_url: https://github.com/windsorcli/cli From b6f532801b61b7dace376ef8eef3bbba3ea740f6 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 22:00:03 -0400 Subject: [PATCH 05/14] split builds --- .github/workflows/ci.yaml | 91 ++++++++++++++++++++++++++++++--------- .goreleaser.yaml | 24 ++++++++--- 2 files changed, 89 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9fed530c8..1102a8309 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -109,18 +109,75 @@ jobs: # GOTOOLCHAIN: 'local' # GOFLAGS: '-buildvcs=false' - release: - runs-on: ubuntu-latest + # release: + # runs-on: ubuntu-latest + # if: startsWith(github.ref, 'refs/tags/') + # # needs: [build-and-test, sast-scan] + + # steps: + # - name: Checkout code + # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # - name: Install GPG + # run: sudo apt-get update && sudo apt-get install -y gnupg + + # - name: Install Aqua + # uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 + # with: + # aqua_version: v2.51.1 + + # - name: Install tools + # run: aqua install + + # - name: Cache Go Modules + # uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + # with: + # path: | + # ~/.cache/go-build + # ~/go/pkg/mod + # key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + # restore-keys: | + # ${{ runner.os }}-go- + + # - name: Install Dependencies + # run: go install ./... + + # - name: Import GPG key + # id: import_gpg + # uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 + # with: + # gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + # passphrase: ${{ secrets.GPG_PASSPHRASE }} + + # - name: Check if prerelease + # id: prerelease + # run: | + # if [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+- ]]; then + # echo "prerelease=true" >> $GITHUB_OUTPUT + # else + # echo "prerelease=false" >> $GITHUB_OUTPUT + # fi + + # - name: Run GoReleaser + # uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 + # with: + # version: "~> v2" + # args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --id=unix --skip=chocolatey + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # GPG_FINGERPRINT: ${{ env.GPG_FINGERPRINT }} + # HOMEBREW_CLI_WRITE_PAT: ${{ secrets.HOMEBREW_CLI_WRITE_PAT }} + # GITHUB_SHA: ${{ github.sha }} + + release-windows: + runs-on: windows-latest if: startsWith(github.ref, 'refs/tags/') - # needs: [build-and-test, sast-scan] + # needs: release steps: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install GPG - run: sudo apt-get update && sudo apt-get install -y gnupg - - name: Install Aqua uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 with: @@ -142,30 +199,22 @@ jobs: - name: Install Dependencies run: go install ./... - - name: Import GPG key - id: import_gpg - uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 - with: - gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.GPG_PASSPHRASE }} - - name: Check if prerelease id: prerelease run: | - if [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+- ]]; then - echo "prerelease=true" >> $GITHUB_OUTPUT - else - echo "prerelease=false" >> $GITHUB_OUTPUT - fi + if ($env:GITHUB_REF -match '^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+-') { + echo "prerelease=true" >> $env:GITHUB_OUTPUT + } else { + echo "prerelease=false" >> $env:GITHUB_OUTPUT + } + shell: pwsh - name: Run GoReleaser uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 with: version: "~> v2" - args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} + args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --id=windows --id-only=chocolatey env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GPG_FINGERPRINT: ${{ env.GPG_FINGERPRINT }} - HOMEBREW_CLI_WRITE_PAT: ${{ secrets.HOMEBREW_CLI_WRITE_PAT }} CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }} GITHUB_SHA: ${{ github.sha }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 7b9d0807a..131e7ac7a 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -10,22 +10,36 @@ before: - go generate ./... builds: - - id: windsor + - id: windows env: - CGO_ENABLED=0 main: ./cmd/windsor goos: - # - darwin - # - linux - windows goarch: - # - arm64 - amd64 + binary: windsor.exe ldflags: - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.version={{ .Version }}'" - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/pkg/secrets.version={{ .Version }}'" - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.commitSHA={{ .Env.GITHUB_SHA }}'" +# - id: unix +# env: +# - CGO_ENABLED=0 +# main: ./cmd/windsor +# goos: +# - darwin +# - linux +# goarch: +# - amd64 +# - arm64 +# binary: windsor +# ldflags: +# - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.version={{ .Version }}'" +# - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/pkg/secrets.version={{ .Version }}'" +# - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.commitSHA={{ .Env.GITHUB_SHA }}'" + # Archive configuration archives: - id: windsor @@ -75,7 +89,7 @@ signs: chocolateys: - name: windsor ids: - - windsor + - windows package_source_url: https://github.com/windsorcli/cli owners: Windsor CLI title: Windsor CLI From f08fdcdc56312b1dacf5a94cbd791f81741a9675 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 22:08:37 -0400 Subject: [PATCH 06/14] Install chocolatey --- .github/workflows/ci.yaml | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1102a8309..ff0122eea 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -178,23 +178,18 @@ jobs: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install Aqua - uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 - with: - aqua_version: v2.51.1 - - - name: Install tools - run: aqua install + - name: Install Chocolatey + shell: powershell + run: | + Set-ExecutionPolicy Bypass -Scope Process -Force + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 + iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) + choco --version - - name: Cache Go Modules - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + - name: Setup Go + uses: actions/setup-go@19bb51245e9c80abacb2e91cc42b33fa478b8639 # v4.2.1 with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + go-version: 1.24.2 - name: Install Dependencies run: go install ./... From fa80e4da46dc9c0187efd2d210b22aeee8fb38d7 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 22:12:03 -0400 Subject: [PATCH 07/14] Don't install go either --- .github/workflows/ci.yaml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ff0122eea..7cf28d97b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -178,22 +178,6 @@ jobs: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install Chocolatey - shell: powershell - run: | - Set-ExecutionPolicy Bypass -Scope Process -Force - [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 - iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) - choco --version - - - name: Setup Go - uses: actions/setup-go@19bb51245e9c80abacb2e91cc42b33fa478b8639 # v4.2.1 - with: - go-version: 1.24.2 - - - name: Install Dependencies - run: go install ./... - - name: Check if prerelease id: prerelease run: | From 7d74c2ec48143eca115c2582bd7184ef47074f03 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 22:18:00 -0400 Subject: [PATCH 08/14] use skip appropriately --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7cf28d97b..5d9fade43 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -192,7 +192,7 @@ jobs: uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 with: version: "~> v2" - args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --id=windows --id-only=chocolatey + args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --skip=brew env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }} From 85de1654b879a5f2074a3119a8face6e1cfe8492 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 22:19:31 -0400 Subject: [PATCH 09/14] skip homebrew --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5d9fade43..7e1a93868 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -192,7 +192,7 @@ jobs: uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 with: version: "~> v2" - args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --skip=brew + args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --skip=homebrew env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }} From 3eff9b86fec057dc0c5160ccc0b3550391d0d9f2 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 22:39:33 -0400 Subject: [PATCH 10/14] Run all on Windows --- .github/workflows/ci.yaml | 88 ++++++++------------------------------- .goreleaser.yaml | 24 +++-------- 2 files changed, 23 insertions(+), 89 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7e1a93868..336688593 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -109,91 +109,39 @@ jobs: # GOTOOLCHAIN: 'local' # GOFLAGS: '-buildvcs=false' - # release: - # runs-on: ubuntu-latest - # if: startsWith(github.ref, 'refs/tags/') - # # needs: [build-and-test, sast-scan] - - # steps: - # - name: Checkout code - # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - # - name: Install GPG - # run: sudo apt-get update && sudo apt-get install -y gnupg - - # - name: Install Aqua - # uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 - # with: - # aqua_version: v2.51.1 - - # - name: Install tools - # run: aqua install - - # - name: Cache Go Modules - # uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - # with: - # path: | - # ~/.cache/go-build - # ~/go/pkg/mod - # key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - # restore-keys: | - # ${{ runner.os }}-go- - - # - name: Install Dependencies - # run: go install ./... - - # - name: Import GPG key - # id: import_gpg - # uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 - # with: - # gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - # passphrase: ${{ secrets.GPG_PASSPHRASE }} - - # - name: Check if prerelease - # id: prerelease - # run: | - # if [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+- ]]; then - # echo "prerelease=true" >> $GITHUB_OUTPUT - # else - # echo "prerelease=false" >> $GITHUB_OUTPUT - # fi - - # - name: Run GoReleaser - # uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 - # with: - # version: "~> v2" - # args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --id=unix --skip=chocolatey - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # GPG_FINGERPRINT: ${{ env.GPG_FINGERPRINT }} - # HOMEBREW_CLI_WRITE_PAT: ${{ secrets.HOMEBREW_CLI_WRITE_PAT }} - # GITHUB_SHA: ${{ github.sha }} - - release-windows: + release: runs-on: windows-latest if: startsWith(github.ref, 'refs/tags/') - # needs: release steps: - name: Checkout code uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Import GPG key + id: import_gpg + uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + - name: Check if prerelease id: prerelease run: | - if ($env:GITHUB_REF -match '^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+-') { - echo "prerelease=true" >> $env:GITHUB_OUTPUT - } else { - echo "prerelease=false" >> $env:GITHUB_OUTPUT - } - shell: pwsh + if [[ "${{ github.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+- ]]; then + echo "prerelease=true" >> $GITHUB_OUTPUT + else + echo "prerelease=false" >> $GITHUB_OUTPUT + fi + shell: bash - name: Run GoReleaser uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 with: version: "~> v2" - args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} --skip=homebrew + args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }} + GPG_FINGERPRINT: ${{ env.GPG_FINGERPRINT }} GITHUB_SHA: ${{ github.sha }} + HOMEBREW_CLI_WRITE_PAT: ${{ secrets.HOMEBREW_CLI_WRITE_PAT }} + CHOCOLATEY_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 131e7ac7a..7b9d0807a 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -10,36 +10,22 @@ before: - go generate ./... builds: - - id: windows + - id: windsor env: - CGO_ENABLED=0 main: ./cmd/windsor goos: + # - darwin + # - linux - windows goarch: + # - arm64 - amd64 - binary: windsor.exe ldflags: - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.version={{ .Version }}'" - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/pkg/secrets.version={{ .Version }}'" - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.commitSHA={{ .Env.GITHUB_SHA }}'" -# - id: unix -# env: -# - CGO_ENABLED=0 -# main: ./cmd/windsor -# goos: -# - darwin -# - linux -# goarch: -# - amd64 -# - arm64 -# binary: windsor -# ldflags: -# - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.version={{ .Version }}'" -# - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/pkg/secrets.version={{ .Version }}'" -# - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.commitSHA={{ .Env.GITHUB_SHA }}'" - # Archive configuration archives: - id: windsor @@ -89,7 +75,7 @@ signs: chocolateys: - name: windsor ids: - - windows + - windsor package_source_url: https://github.com/windsorcli/cli owners: Windsor CLI title: Windsor CLI From 5240b65b226ffd7f32e09d9a1f5c4454510016c0 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Thu, 8 May 2025 23:20:44 -0400 Subject: [PATCH 11/14] add url_templaet --- .goreleaser.yaml | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 7b9d0807a..13a686b4e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -61,16 +61,29 @@ signs: # brews: # - name: windsor -# directory: Formula # repository: # owner: windsorcli # name: homebrew-cli # branch: main # token: "{{ .Env.HOMEBREW_CLI_WRITE_PAT }}" -# homepage: "https://windsorcli.github.io" +# commit_author: +# name: goreleaserbot +# email: bot@goreleaser.com +# homepage: "https://windsorcli.github.io" # description: "The Windsor Command Line Interface" -# ids: -# - windsor +# license: "MIT" +# skip_upload: auto +# download_strategy: GithubPrivateRepositoryReleaseDownloadStrategy +# custom_require: "lib/custom_download_strategy" +# install: | +# bin.install "windsor" +# # Install shell completions +# output = Utils.safe_popen_read("#{bin}/windsor", "completion", "bash") +# (bash_completion/"windsor").write output +# output = Utils.safe_popen_read("#{bin}/windsor", "completion", "zsh") +# (zsh_completion/"_windsor").write output +# output = Utils.safe_popen_read("#{bin}/windsor", "completion", "fish") +# (fish_completion/"windsor.fish").write output chocolateys: - name: windsor @@ -101,6 +114,6 @@ chocolateys: Your PowerShell profile is located at: $PROFILE release_notes: "https://github.com/windsorcli/cli/releases/tag/v{{ .Version }}" - skip_publish: false api_key: "{{ .Env.CHOCOLATEY_API_KEY }}" source_repo: "https://push.chocolatey.org/" + url_template: "https://github.com/windsorcli/cli/releases/download/v{{ .Version }}/windsor_{{ .Version }}_windows_amd64.tar.gz" From 3e0c520a9d8e66aaa5f57be63a09e17fea644ee2 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Fri, 9 May 2025 08:26:33 -0400 Subject: [PATCH 12/14] Use zip for windows --- .goreleaser.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 13a686b4e..4cafd8730 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -29,7 +29,11 @@ builds: # Archive configuration archives: - id: windsor - formats: ["tar.gz"] + formats: + - tar.gz + format_overrides: + - goos: windows + format: zip changelog: sort: asc @@ -116,4 +120,4 @@ chocolateys: release_notes: "https://github.com/windsorcli/cli/releases/tag/v{{ .Version }}" api_key: "{{ .Env.CHOCOLATEY_API_KEY }}" source_repo: "https://push.chocolatey.org/" - url_template: "https://github.com/windsorcli/cli/releases/download/v{{ .Version }}/windsor_{{ .Version }}_windows_amd64.tar.gz" + url_template: "https://github.com/windsorcli/cli/releases/download/v{{ .Version }}/windsor_{{ .Version }}_windows_amd64.zip" From 44a5b8fe72847e8852017df71624383d33761150 Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Fri, 9 May 2025 09:36:48 -0400 Subject: [PATCH 13/14] enable homebrew --- .github/workflows/ci.yaml | 183 +++++++++++++++++++------------------- .goreleaser.yaml | 56 ++++++------ 2 files changed, 120 insertions(+), 119 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 336688593..fa93241ee 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,104 +13,105 @@ permissions: issues: read pull-requests: read jobs: - # build-and-test: - # strategy: - # matrix: - # os: [ubuntu-latest, windows-latest, macos-latest] - # arch: [amd64, arm64] - # exclude: - # - os: windows-latest - # arch: arm64 - # runs-on: ${{ matrix.os }} - - # steps: - # - name: Checkout code - # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - # - name: Install Aqua - # uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 - # with: - # aqua_version: v2.51.1 - - # - name: Install tools - # run: aqua install - - # - name: Cache Go Modules - # uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - # with: - # path: | - # ~/.cache/go-build - # ~/go/pkg/mod - # key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - # restore-keys: | - # ${{ runner.os }}-go- + build-and-test: + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + arch: [amd64, arm64] + exclude: + - os: windows-latest + arch: arm64 + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install Aqua + uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 + with: + aqua_version: v2.51.1 + + - name: Install tools + run: aqua install + + - name: Cache Go Modules + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- - # - name: Install Dependencies - # run: go install ./... + - name: Install Dependencies + run: go install ./... - # - name: Run tests - # run: task test - - # - name: Test Build Windsor CLI on macOS/Linux - # if: ${{ matrix.os != 'windows-latest' }} - # run: | - # VERSION=$(echo "${GITHUB_REF}" | sed 's/refs\/heads\///' | sed 's/refs\/tags\///') - # echo "Testing build for version: $VERSION" - # COMMIT_SHA=${{ github.sha }} - # if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then - # GOOS=linux GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go - # elif [ "${{ matrix.os }}" == "macos-latest" ]; then - # GOOS=darwin GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go - # fi - - # - name: Test Build Windsor CLI on Windows - # if: ${{ matrix.os == 'windows-latest' }} - # run: | - # $env:VERSION = $env:GITHUB_REF -replace 'refs/heads/', '' -replace 'refs/tags/', '' - # echo "Testing build for version: $env:VERSION" - # $env:COMMIT_SHA = "${{ github.sha }}" - # $env:GOOS = "windows" - # $env:GOARCH = "${{ matrix.arch }}" - # go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$env:VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$env:COMMIT_SHA'" -o NUL cmd\windsor\main.go - # shell: pwsh - - # sast-scan: - # runs-on: ubuntu-latest - # steps: - # - name: Checkout code - # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - # - name: Install Aqua - # uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 - # with: - # aqua_version: v2.51.1 - - # - name: Install tools - # run: aqua install - - # - name: Cache Go Modules - # uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 - # with: - # path: | - # ~/.cache/go-build - # ~/go/pkg/mod - # key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - # restore-keys: | - # ${{ runner.os }}-go- + - name: Run tests + run: task test + + - name: Test Build Windsor CLI on macOS/Linux + if: ${{ matrix.os != 'windows-latest' }} + run: | + VERSION=$(echo "${GITHUB_REF}" | sed 's/refs\/heads\///' | sed 's/refs\/tags\///') + echo "Testing build for version: $VERSION" + COMMIT_SHA=${{ github.sha }} + if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then + GOOS=linux GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go + elif [ "${{ matrix.os }}" == "macos-latest" ]; then + GOOS=darwin GOARCH=${{ matrix.arch }} go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$COMMIT_SHA'" -o /dev/null cmd/windsor/main.go + fi + + - name: Test Build Windsor CLI on Windows + if: ${{ matrix.os == 'windows-latest' }} + run: | + $env:VERSION = $env:GITHUB_REF -replace 'refs/heads/', '' -replace 'refs/tags/', '' + echo "Testing build for version: $env:VERSION" + $env:COMMIT_SHA = "${{ github.sha }}" + $env:GOOS = "windows" + $env:GOARCH = "${{ matrix.arch }}" + go build -ldflags "-X 'github.com/${{ github.repository }}/cmd.version=$env:VERSION' -X 'github.com/${{ github.repository }}/cmd.commitSHA=$env:COMMIT_SHA'" -o NUL cmd\windsor\main.go + shell: pwsh + + sast-scan: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install Aqua + uses: aquaproj/aqua-installer@5e54e5cee8a95ee2ce7c04cb993da6dfad13e59c # v3.1.2 + with: + aqua_version: v2.51.1 + + - name: Install tools + run: aqua install + + - name: Cache Go Modules + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- - # - name: Install Dependencies - # run: go install ./... + - name: Install Dependencies + run: go install ./... - # - name: Run Gosec Security Scanner - # uses: securego/gosec@955a68d0d19f4afb7503068f95059f7d0c529017 # v2.22.3 - # with: - # args: ./... - # env: - # GOTOOLCHAIN: 'local' - # GOFLAGS: '-buildvcs=false' + - name: Run Gosec Security Scanner + uses: securego/gosec@955a68d0d19f4afb7503068f95059f7d0c529017 # v2.22.3 + with: + args: ./... + env: + GOTOOLCHAIN: 'local' + GOFLAGS: '-buildvcs=false' release: runs-on: windows-latest + needs: [build-and-test, sast-scan] if: startsWith(github.ref, 'refs/tags/') steps: diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 4cafd8730..901056dcc 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -15,11 +15,11 @@ builds: - CGO_ENABLED=0 main: ./cmd/windsor goos: - # - darwin - # - linux + - darwin + - linux - windows goarch: - # - arm64 + - arm64 - amd64 ldflags: - "-X 'github.com/{{ .Env.GITHUB_REPOSITORY }}/cmd.version={{ .Version }}'" @@ -63,31 +63,31 @@ binary_signs: signs: - artifacts: checksum -# brews: -# - name: windsor -# repository: -# owner: windsorcli -# name: homebrew-cli -# branch: main -# token: "{{ .Env.HOMEBREW_CLI_WRITE_PAT }}" -# commit_author: -# name: goreleaserbot -# email: bot@goreleaser.com -# homepage: "https://windsorcli.github.io" -# description: "The Windsor Command Line Interface" -# license: "MIT" -# skip_upload: auto -# download_strategy: GithubPrivateRepositoryReleaseDownloadStrategy -# custom_require: "lib/custom_download_strategy" -# install: | -# bin.install "windsor" -# # Install shell completions -# output = Utils.safe_popen_read("#{bin}/windsor", "completion", "bash") -# (bash_completion/"windsor").write output -# output = Utils.safe_popen_read("#{bin}/windsor", "completion", "zsh") -# (zsh_completion/"_windsor").write output -# output = Utils.safe_popen_read("#{bin}/windsor", "completion", "fish") -# (fish_completion/"windsor.fish").write output +brews: + - name: windsor + repository: + owner: windsorcli + name: homebrew-cli + branch: main + token: "{{ .Env.HOMEBREW_CLI_WRITE_PAT }}" + commit_author: + name: goreleaserbot + email: bot@goreleaser.com + homepage: "https://windsorcli.github.io" + description: "The Windsor Command Line Interface" + license: "MPL-2.0" + skip_upload: auto + download_strategy: GithubPrivateRepositoryReleaseDownloadStrategy + custom_require: "lib/custom_download_strategy" + install: | + bin.install "windsor" + # Install shell completions + output = Utils.safe_popen_read("#{bin}/windsor", "completion", "bash") + (bash_completion/"windsor").write output + output = Utils.safe_popen_read("#{bin}/windsor", "completion", "zsh") + (zsh_completion/"_windsor").write output + output = Utils.safe_popen_read("#{bin}/windsor", "completion", "fish") + (fish_completion/"windsor.fish").write output chocolateys: - name: windsor From 7fdfa9e6fb84e26ff25e8a4b00eb136fa674ceba Mon Sep 17 00:00:00 2001 From: Ryan VanGundy Date: Fri, 9 May 2025 22:21:33 -0400 Subject: [PATCH 14/14] Skip specific package mangers --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fa93241ee..24d183627 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -139,7 +139,7 @@ jobs: uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 with: version: "~> v2" - args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=publish' || '' }} + args: release --clean ${{ steps.prerelease.outputs.prerelease == 'true' && '--skip=chocolatey,homebrew' || '' }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GPG_FINGERPRINT: ${{ env.GPG_FINGERPRINT }}