Skip to content

Commit 18a5470

Browse files
committed
fix: update runSetup to use CheckLatestTag and pass tag to Install
CheckLatestVersion was removed in favor of CheckLatestTag, but runSetup was missed. Also passes the resolved tag to Install so the upgrade installs the exact version that was checked.
1 parent 395bb38 commit 18a5470

File tree

3 files changed

+22
-164
lines changed

3 files changed

+22
-164
lines changed

cmd/greywall/main.go

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -586,30 +586,6 @@ func runCommand(cmd *cobra.Command, args []string) error {
586586
}
587587
}
588588

589-
// Inject keyring secrets for active profiles (Linux only).
590-
// This reads from the host keyring before sandboxing blocks D-Bus access.
591-
// Check the command itself and any explicitly loaded profiles.
592-
if !learning {
593-
profileNames := []string{cmdName}
594-
if profileName != "" {
595-
for _, name := range strings.Split(profileName, ",") {
596-
name = strings.TrimSpace(name)
597-
if name != "" {
598-
profileNames = append(profileNames, name)
599-
}
600-
}
601-
}
602-
for _, name := range profileNames {
603-
canonical := profiles.IsKnownAgent(name)
604-
if canonical == "" {
605-
continue
606-
}
607-
if secrets := profiles.GetKeyringSecrets(canonical); secrets != nil {
608-
hardenedEnv = append(hardenedEnv, profiles.ResolveKeyringSecrets(secrets, debug)...)
609-
}
610-
}
611-
}
612-
613589
execCmd := exec.Command("sh", "-c", sandboxedCommand) //nolint:gosec // sandboxedCommand is constructed from user input - intentional
614590
execCmd.Env = hardenedEnv
615591
execCmd.Stdin = os.Stdin
@@ -805,9 +781,9 @@ func runCheck(_ *cobra.Command, _ []string) error {
805781
fmt.Println(sandbox.CheckFail("greyproxy running"))
806782
steps = append(steps, "greywall setup")
807783
}
808-
if latestTag, err := proxy.CheckLatestTag(false); err == nil {
809-
latest := strings.TrimPrefix(latestTag, "v")
810-
if proxy.IsOlderVersion(status.Version, latest) {
784+
if latestTag, err := proxy.CheckLatestTag(); err == nil {
785+
if proxy.IsOlderVersion(status.Version, latestTag) {
786+
latest := strings.TrimPrefix(latestTag, "v")
811787
fmt.Println(sandbox.CheckFail(fmt.Sprintf("greyproxy up-to-date (v%s available, installed v%s)", latest, status.Version)))
812788
steps = append(steps, upgradeHint)
813789
}
@@ -859,14 +835,15 @@ func runSetup(_ *cobra.Command, _ []string) error {
859835
status := proxy.Detect()
860836

861837
if status.Installed && status.Running {
862-
latest, err := proxy.CheckLatestVersion()
838+
latestTag, err := proxy.CheckLatestTag()
863839
if err != nil {
864840
fmt.Fprintf(os.Stderr, "Warning: could not check for updates: %v\n", err)
865841
fmt.Printf("greyproxy is already installed (v%s) and running.\n", status.Version)
866842
fmt.Printf("Run 'greywall check' for full status.\n")
867843
return nil
868844
}
869-
if proxy.IsOlderVersion(status.Version, latest) {
845+
if proxy.IsOlderVersion(status.Version, latestTag) {
846+
latest := strings.TrimPrefix(latestTag, "v")
870847
fmt.Printf("greyproxy update available: v%s -> v%s\n", status.Version, latest)
871848
if proxy.IsBrewManaged(status.Path) {
872849
fmt.Printf("greyproxy is managed by Homebrew. To update, run:\n")

internal/proxy/install.go

Lines changed: 11 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ type asset struct {
3838
// InstallOptions controls the greyproxy installation behavior.
3939
type InstallOptions struct {
4040
Output io.Writer // progress output (typically os.Stderr)
41-
Tag string // specific tag to install; if empty, uses latest stable
42-
Beta bool // if Tag is empty and Beta is true, fetches latest pre-release tag
4341
}
4442

4543
// IsOlderVersion returns true if current is strictly older than latest,
4644
// or if current is not a valid semver string (e.g. "dev").
47-
// Both strings should be in "major.minor.patch" format (no "v" prefix).
45+
// Accepts strings with or without a "v" prefix (e.g. "v1.2.3" or "1.2.3").
4846
func IsOlderVersion(current, latest string) bool {
47+
current = strings.TrimPrefix(current, "v")
48+
latest = strings.TrimPrefix(latest, "v")
4949
cp := strings.SplitN(current, ".", 3)
5050
lp := strings.SplitN(latest, ".", 3)
5151
if len(lp) != 3 {
@@ -85,21 +85,7 @@ func Install(opts InstallOptions) error {
8585
opts.Output = os.Stderr
8686
}
8787

88-
// Resolve which tag to install
89-
var rel *release
90-
var err error
91-
switch {
92-
case opts.Tag != "":
93-
rel, err = fetchReleaseFor(nil, "", githubOwner, githubRepo, opts.Tag)
94-
case opts.Beta:
95-
tag, tagErr := fetchLatestPreReleaseTagFor(nil, "", githubOwner, githubRepo)
96-
if tagErr != nil {
97-
return fmt.Errorf("failed to fetch latest pre-release: %w", tagErr)
98-
}
99-
rel, err = fetchReleaseFor(nil, "", githubOwner, githubRepo, tag)
100-
default:
101-
rel, err = fetchLatestRelease()
102-
}
88+
rel, err := fetchLatestRelease()
10389
if err != nil {
10490
return fmt.Errorf("failed to fetch release: %w", err)
10591
}
@@ -155,26 +141,16 @@ func Install(opts InstallOptions) error {
155141
}
156142

157143
// CheckLatestTag returns the latest greyproxy release tag (with "v" prefix).
158-
// If beta is true, returns the latest pre-release tag.
159-
func CheckLatestTag(beta bool) (string, error) {
160-
return CheckLatestTagFor(githubOwner, githubRepo, beta)
161-
}
162-
163-
// CheckLatestTagFor returns the latest release tag for any GitHub repo.
164-
// If beta is true, returns the latest pre-release tag; otherwise returns the latest stable tag.
165-
func CheckLatestTagFor(owner, repo string, beta bool) (string, error) {
166-
return checkLatestTagFor(nil, "", owner, repo, beta)
144+
func CheckLatestTag() (string, error) {
145+
return checkLatestTag(nil, "")
167146
}
168147

169-
func checkLatestTagFor(client *http.Client, apiBase, owner, repo string, beta bool) (string, error) {
170-
if !beta {
171-
rel, err := fetchReleaseFor(client, apiBase, owner, repo, "latest")
172-
if err != nil {
173-
return "", err
174-
}
175-
return rel.TagName, nil
148+
func checkLatestTag(client *http.Client, apiBase string) (string, error) {
149+
rel, err := fetchReleaseFor(client, apiBase, githubOwner, githubRepo, "latest")
150+
if err != nil {
151+
return "", err
176152
}
177-
return fetchLatestPreReleaseTagFor(client, apiBase, owner, repo)
153+
return rel.TagName, nil
178154
}
179155

180156
// fetchLatestRelease queries the GitHub API for the latest greyproxy release.
@@ -337,50 +313,3 @@ func fetchReleaseFor(client *http.Client, apiBase, owner, repo, endpoint string)
337313
}
338314
return &rel, nil
339315
}
340-
341-
// fetchLatestPreReleaseTagFor returns the most recent pre-release tag for the given repo.
342-
// client and apiBase are optional; nil/empty use production defaults.
343-
func fetchLatestPreReleaseTagFor(client *http.Client, apiBase, owner, repo string) (string, error) {
344-
if client == nil {
345-
client = &http.Client{Timeout: apiTimeout}
346-
}
347-
if apiBase == "" {
348-
apiBase = "https://api.github.com"
349-
}
350-
apiURL := fmt.Sprintf("%s/repos/%s/%s/releases?per_page=20", apiBase, owner, repo)
351-
352-
ctx, cancel := context.WithTimeout(context.Background(), apiTimeout)
353-
defer cancel()
354-
355-
req, err := http.NewRequestWithContext(ctx, http.MethodGet, apiURL, nil)
356-
if err != nil {
357-
return "", err
358-
}
359-
req.Header.Set("Accept", "application/vnd.github+json")
360-
req.Header.Set("User-Agent", "greywall-setup")
361-
362-
resp, err := client.Do(req) //nolint:gosec // apiURL is built from controlled inputs
363-
if err != nil {
364-
return "", fmt.Errorf("GitHub API request failed: %w", err)
365-
}
366-
defer func() { _ = resp.Body.Close() }()
367-
368-
if resp.StatusCode != http.StatusOK {
369-
return "", fmt.Errorf("GitHub API returned status %d", resp.StatusCode)
370-
}
371-
372-
var releases []struct {
373-
TagName string `json:"tag_name"`
374-
PreRelease bool `json:"prerelease"`
375-
}
376-
if err := json.NewDecoder(resp.Body).Decode(&releases); err != nil {
377-
return "", fmt.Errorf("failed to parse releases response: %w", err)
378-
}
379-
380-
for _, r := range releases {
381-
if r.PreRelease {
382-
return r.TagName, nil
383-
}
384-
}
385-
return "", fmt.Errorf("no pre-release found for %s/%s", owner, repo)
386-
}

internal/proxy/install_test.go

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func TestIsOlderVersion(t *testing.T) {
4646
}
4747
}
4848

49-
func TestCheckLatestTagFor_Stable(t *testing.T) {
49+
func TestCheckLatestTag_OK(t *testing.T) {
5050
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
51-
if r.URL.Path != "/repos/owner/repo/releases/latest" {
51+
if r.URL.Path != "/repos/greyhavenhq/greyproxy/releases/latest" {
5252
http.NotFound(w, r)
5353
return
5454
}
@@ -57,7 +57,7 @@ func TestCheckLatestTagFor_Stable(t *testing.T) {
5757
}))
5858
defer srv.Close()
5959

60-
tag, err := checkLatestTagFor(srv.Client(), srv.URL, "owner", "repo", false)
60+
tag, err := checkLatestTag(srv.Client(), srv.URL)
6161
if err != nil {
6262
t.Fatalf("unexpected error: %v", err)
6363
}
@@ -66,61 +66,13 @@ func TestCheckLatestTagFor_Stable(t *testing.T) {
6666
}
6767
}
6868

69-
func TestCheckLatestTagFor_Beta(t *testing.T) {
70-
releases := []struct {
71-
TagName string `json:"tag_name"`
72-
PreRelease bool `json:"prerelease"`
73-
}{
74-
{TagName: "v2.0.0-beta.1", PreRelease: true},
75-
{TagName: "v1.9.0", PreRelease: false},
76-
}
77-
78-
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
79-
if r.URL.Path != "/repos/owner/repo/releases" {
80-
http.NotFound(w, r)
81-
return
82-
}
83-
w.Header().Set("Content-Type", "application/json")
84-
_ = json.NewEncoder(w).Encode(releases)
85-
}))
86-
defer srv.Close()
87-
88-
tag, err := checkLatestTagFor(srv.Client(), srv.URL, "owner", "repo", true)
89-
if err != nil {
90-
t.Fatalf("unexpected error: %v", err)
91-
}
92-
if tag != "v2.0.0-beta.1" {
93-
t.Errorf("got tag %q, want %q", tag, "v2.0.0-beta.1")
94-
}
95-
}
96-
97-
func TestCheckLatestTagFor_BetaNoneFound(t *testing.T) {
98-
releases := []struct {
99-
TagName string `json:"tag_name"`
100-
PreRelease bool `json:"prerelease"`
101-
}{
102-
{TagName: "v1.9.0", PreRelease: false},
103-
}
104-
105-
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
106-
w.Header().Set("Content-Type", "application/json")
107-
_ = json.NewEncoder(w).Encode(releases)
108-
}))
109-
defer srv.Close()
110-
111-
_, err := checkLatestTagFor(srv.Client(), srv.URL, "owner", "repo", true)
112-
if err == nil {
113-
t.Fatal("expected error when no pre-release found, got nil")
114-
}
115-
}
116-
117-
func TestCheckLatestTagFor_APIError(t *testing.T) {
69+
func TestCheckLatestTag_APIError(t *testing.T) {
11870
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
11971
http.Error(w, "rate limited", http.StatusTooManyRequests)
12072
}))
12173
defer srv.Close()
12274

123-
_, err := checkLatestTagFor(srv.Client(), srv.URL, "owner", "repo", false)
75+
_, err := checkLatestTag(srv.Client(), srv.URL)
12476
if err == nil {
12577
t.Fatal("expected error on non-200 response, got nil")
12678
}

0 commit comments

Comments
 (0)