Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -389,25 +389,43 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
contents: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7
with:
go-version-file: go.mod

- name: download darwin CLI artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
- name: build Homebrew-managed CLI artifacts
uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7
with:
name: devsy-darwin
path: ${{ runner.temp }}/devsy-bin/
distribution: goreleaser
version: "~> v2"
args: build --id devsy-homebrew --snapshot
env:
DEVSY_CLI_VERSION: ${{ inputs.tag || github.ref_name }}
DEVSY_POSTHOG_API_KEY: ${{ secrets.DEVSY_POSTHOG_API_KEY }}

- name: download linux CLI artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
- name: stage Homebrew-managed CLI artifacts
run: |
mkdir -p "${{ runner.temp }}/devsy-bin"
find dist -type f -name 'devsy-homebrew-*' -exec cp {} "${{ runner.temp }}/devsy-bin/" \;

- name: verify Homebrew-managed update guidance
run: |
set +e
output=$("${{ runner.temp }}/devsy-bin/devsy-homebrew-linux-amd64" update 2>&1)
status=$?
set -e
test "$status" -ne 0
grep -F "brew upgrade devsy" <<<"$output"

- name: upload Homebrew-managed CLI release assets
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3
with:
name: devsy-linux
path: ${{ runner.temp }}/devsy-bin/
tag_name: ${{ inputs.tag || github.ref_name }}
files: ${{ runner.temp }}/devsy-bin/devsy-homebrew-*

- name: download macOS dmg artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
Expand Down
8 changes: 8 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ builds:
env:
- CGO_ENABLED=0

- id: devsy-homebrew
goos: [linux, darwin]
goarch: [amd64, arm64]
binary: devsy-homebrew-{{ .Os }}-{{ .Arch }}
ldflags: -s -w -X main.build={{ .Env.DEVSY_CLI_VERSION }} -X main.commit={{ .Commit }} -X main.date={{ .Date }} -X github.com/devsy-org/devsy/pkg/version.version={{ .Env.DEVSY_CLI_VERSION }} -X github.com/devsy-org/devsy/pkg/version.packageManager=homebrew -X github.com/devsy-org/devsy/pkg/telemetry/analytics.posthogAPIKey={{ envOrDefault "DEVSY_POSTHOG_API_KEY" "" }}
env:
- CGO_ENABLED=0

- id: devsy-dev
goos: [linux, darwin]
goarch: [amd64, arm64]
Expand Down
17 changes: 17 additions & 0 deletions cmd/update/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
cliflags "github.com/devsy-org/devsy/pkg/flags"
"github.com/devsy-org/devsy/pkg/flags/names"
"github.com/devsy-org/devsy/pkg/selfupdate"
"github.com/devsy-org/devsy/pkg/version"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -42,6 +43,9 @@ func NewUpdateCmd() *cobra.Command {
}
},
RunE: func(cobraCmd *cobra.Command, args []string) error {
if err := checkPackageManager(version.GetPackageManager()); err != nil {
return err
}
ctx := cobraCmd.Context()
opts := selfupdate.Options{
Version: cmd.Version,
Expand Down Expand Up @@ -78,3 +82,16 @@ func NewUpdateCmd() *cobra.Command {
)
return updateCmd
}

func checkPackageManager(packageManager string) error {
switch packageManager {
case "", "direct":
return nil
case "homebrew":
return fmt.Errorf(
"this Devsy installation is managed by Homebrew; run `brew upgrade devsy` to update",
)
default:
return fmt.Errorf("unsupported package manager %q", packageManager)
}
}
18 changes: 9 additions & 9 deletions hack/homebrew_formula/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ type platform struct {
}

var platforms = []platform{
{OS: "macos", Arch: "arm", Binary: "devsy-darwin-arm64"},
{OS: "macos", Arch: "intel", Binary: "devsy-darwin-amd64"},
{OS: "linux", Arch: "arm", Binary: "devsy-linux-arm64"},
{OS: "linux", Arch: "intel", Binary: "devsy-linux-amd64"},
{OS: "macos", Arch: "arm", Binary: "devsy-homebrew-darwin-arm64"},
{OS: "macos", Arch: "intel", Binary: "devsy-homebrew-darwin-amd64"},
{OS: "linux", Arch: "arm", Binary: "devsy-homebrew-linux-arm64"},
{OS: "linux", Arch: "intel", Binary: "devsy-homebrew-linux-amd64"},
}

const formulaTmpl = `class Devsy < Formula
Expand All @@ -36,28 +36,28 @@ const formulaTmpl = `class Devsy < Formula

on_macos do
on_arm do
url "{{ (index .Platforms "macos/arm").URL }}"
url "{{ (index .Platforms "macos/arm").URL }}" using: :nounzip
sha256 "{{ (index .Platforms "macos/arm").SHA256 }}"
end
on_intel do
url "{{ (index .Platforms "macos/intel").URL }}"
url "{{ (index .Platforms "macos/intel").URL }}" using: :nounzip
sha256 "{{ (index .Platforms "macos/intel").SHA256 }}"
end
end

on_linux do
on_arm do
url "{{ (index .Platforms "linux/arm").URL }}"
url "{{ (index .Platforms "linux/arm").URL }}" using: :nounzip
sha256 "{{ (index .Platforms "linux/arm").SHA256 }}"
end
on_intel do
url "{{ (index .Platforms "linux/intel").URL }}"
url "{{ (index .Platforms "linux/intel").URL }}" using: :nounzip
sha256 "{{ (index .Platforms "linux/intel").SHA256 }}"
end
end

def install
bin.install Dir["devsy-*"].first => "devsy"
bin.install Dir["devsy-homebrew-*"].first => "devsy"
end

test do
Expand Down
29 changes: 23 additions & 6 deletions hack/homebrew_formula/main_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"fmt"
"os"
"path/filepath"
"strings"
Expand All @@ -25,26 +26,42 @@ func TestRender(t *testing.T) {
t.Fatalf("render: %v", err)
}

// sha256("content-devsy-darwin-arm64")
const wantARM = "9bc996e636ac5321e2aae6bd3fb421c5ea82b34a5b20e2c9fd65cc81b2f3753e"
// sha256("content-devsy-homebrew-darwin-arm64")
const wantARM = "8d309b67abfc5861b1bfb39ea9ed2eda8622eb3aa1f82131cbbefce2bb6ffad7"

for _, want := range []string{
`version "1.2.3"`, // leading v stripped
`license "MPL-2.0"`,
"https://github.com/devsy-org/devsy/releases/download/v1.2.3/devsy-darwin-arm64",
"https://github.com/devsy-org/devsy/releases/download/v1.2.3/devsy-linux-amd64",
"https://github.com/devsy-org/devsy/releases/download/v1.2.3/devsy-homebrew-darwin-arm64",
"https://github.com/devsy-org/devsy/releases/download/v1.2.3/devsy-homebrew-linux-amd64",
`sha256 "` + wantARM + `"`,
`bin.install Dir["devsy-*"].first => "devsy"`,
`bin.install Dir["devsy-homebrew-*"].first => "devsy"`,
} {
if !strings.Contains(out, want) {
t.Errorf("formula missing %q\n---\n%s", want, out)
}
}

for _, p := range platforms {
want := fmt.Sprintf(
`url "%s" using: :nounzip`,
assetURL("devsy-org/devsy", "v1.2.3", p.Binary),
)
if !strings.Contains(out, want) {
t.Errorf(
"formula missing raw binary URL option for %s/%s: %q\n---\n%s",
p.OS,
p.Arch,
want,
out,
)
}
}
}

func TestRenderMissingBinary(t *testing.T) {
dir := writeBinaries(t)
if err := os.Remove(filepath.Join(dir, "devsy-linux-arm64")); err != nil {
if err := os.Remove(filepath.Join(dir, "devsy-homebrew-linux-arm64")); err != nil {
t.Fatal(err)
}
if _, err := render(dir, "devsy-org/devsy", "v1.2.3"); err == nil {
Expand Down
10 changes: 10 additions & 0 deletions pkg/version/package_manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package version

// packageManager is injected at build time by package-managed distributions.
// An empty value means the binary owns its update lifecycle.
var packageManager string

// GetPackageManager identifies the package manager responsible for this binary.
func GetPackageManager() string {
return packageManager
}
Loading