mirror of
https://github.com/chenasraf/sofmani.git
synced 2026-05-17 17:28:04 +00:00
feat: github release add archive_bin_name option
This commit is contained in:
@@ -315,6 +315,22 @@ These fields are shared by all installer types. Some fields may vary in behavior
|
||||
download_filename: myapp_{tag}_linux.tar.gz # outputs: myapp_v1.0.0_linux.tar.gz
|
||||
```
|
||||
|
||||
- `opts.archive_bin_name`: The name of the binary file inside the archive (tar/zip).
|
||||
Use this when the filename inside the archive differs from the desired output `bin_name`.
|
||||
If not set, falls back to `bin_name` (or the installer name).
|
||||
|
||||
```yaml
|
||||
- name: cospend-cli
|
||||
bin_name: cospend
|
||||
type: github-release
|
||||
opts:
|
||||
repository: chenasraf/cospend-cli
|
||||
destination: ~/.local/bin
|
||||
strategy: tar
|
||||
download_filename: cospend-cli-linux-{{ .Arch }}.tar.gz
|
||||
archive_bin_name: cospend-cli # file inside the tar is "cospend-cli", output will be "cospend"
|
||||
```
|
||||
|
||||
- `opts.github_token`: GitHub personal access token for authenticated API requests.
|
||||
Authenticated requests have a much higher rate limit (5,000/hour vs 60/hour for
|
||||
unauthenticated).
|
||||
|
||||
@@ -40,6 +40,10 @@ type GitHubReleaseOpts struct {
|
||||
// GithubToken is the GitHub personal access token for authenticated API requests.
|
||||
// Supports environment variable expansion (e.g., "$GITHUB_TOKEN" or "${GITHUB_TOKEN}").
|
||||
GithubToken *string
|
||||
// ArchiveBinName is the name of the binary file inside the archive (tar/zip).
|
||||
// Use this when the filename inside the archive differs from the desired output bin_name.
|
||||
// If not set, falls back to bin_name (or the installer name).
|
||||
ArchiveBinName *string
|
||||
}
|
||||
|
||||
// GitHubReleaseInstallStrategy represents the installation strategy for a GitHub release.
|
||||
@@ -193,7 +197,7 @@ func (i *GitHubReleaseInstaller) Install() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Debug("Strategy 'tar': copying binary '%s' to destination", i.GetBinName())
|
||||
logger.Debug("Strategy 'tar': copying binary '%s' to destination", i.GetArchiveBinName())
|
||||
success, err = i.CopyExtractedFile(out, tmpDir)
|
||||
if !success {
|
||||
return fmt.Errorf("failed to copy extracted file: %w", err)
|
||||
@@ -210,7 +214,7 @@ func (i *GitHubReleaseInstaller) Install() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Debug("Strategy 'zip': copying binary '%s' to destination", i.GetBinName())
|
||||
logger.Debug("Strategy 'zip': copying binary '%s' to destination", i.GetArchiveBinName())
|
||||
success, err = i.CopyExtractedFile(out, tmpDir)
|
||||
if !success {
|
||||
return fmt.Errorf("failed to copy extracted file: %w", err)
|
||||
@@ -299,6 +303,16 @@ func (i *GitHubReleaseInstaller) GetBinName() string {
|
||||
return filepath.Base(*i.Info.Name)
|
||||
}
|
||||
|
||||
// GetArchiveBinName returns the name of the binary file inside the archive.
|
||||
// It uses ArchiveBinName from opts if provided, otherwise falls back to GetBinName().
|
||||
func (i *GitHubReleaseInstaller) GetArchiveBinName() string {
|
||||
opts := i.GetOpts()
|
||||
if opts.ArchiveBinName != nil {
|
||||
return *opts.ArchiveBinName
|
||||
}
|
||||
return i.GetBinName()
|
||||
}
|
||||
|
||||
// CopyExtractedFile copies the extracted file from a temporary directory to the final destination.
|
||||
func (i *GitHubReleaseInstaller) CopyExtractedFile(out *os.File, tmpDir string) (bool, error) {
|
||||
binFile, err := os.Create(out.Name())
|
||||
@@ -310,7 +324,7 @@ func (i *GitHubReleaseInstaller) CopyExtractedFile(out *os.File, tmpDir string)
|
||||
logger.Warn("failed to close binFile %s: %v", binFile.Name(), cerr)
|
||||
}
|
||||
}()
|
||||
tmpBinFile, err := os.Open(filepath.Join(tmpDir, i.GetBinName()))
|
||||
tmpBinFile, err := os.Open(filepath.Join(tmpDir, i.GetArchiveBinName()))
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to open temporary file: %w", err)
|
||||
}
|
||||
@@ -397,6 +411,9 @@ func (i *GitHubReleaseInstaller) GetOpts() *GitHubReleaseOpts {
|
||||
token = utils.GetRealPath(i.GetData().Environ(), token)
|
||||
opts.GithubToken = &token
|
||||
}
|
||||
if archiveBinName, ok := (*info.Opts)["archive_bin_name"].(string); ok {
|
||||
opts.ArchiveBinName = &archiveBinName
|
||||
}
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
@@ -175,6 +175,45 @@ func TestGitHubReleaseGetBinName(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestGitHubReleaseGetArchiveBinName(t *testing.T) {
|
||||
logger.InitLogger(false)
|
||||
|
||||
t.Run("returns archive_bin_name when set", func(t *testing.T) {
|
||||
binName := "cospend"
|
||||
data := &appconfig.InstallerData{
|
||||
Name: strPtr("cospend-cli"),
|
||||
Type: appconfig.InstallerTypeGitHubRelease,
|
||||
BinName: &binName,
|
||||
Opts: &map[string]any{
|
||||
"archive_bin_name": "cospend-cli",
|
||||
},
|
||||
}
|
||||
installer := newTestGitHubReleaseInstaller(data)
|
||||
assert.Equal(t, "cospend-cli", installer.GetArchiveBinName())
|
||||
assert.Equal(t, "cospend", installer.GetBinName())
|
||||
})
|
||||
|
||||
t.Run("falls back to bin_name when archive_bin_name not set", func(t *testing.T) {
|
||||
binName := "custom-bin"
|
||||
data := &appconfig.InstallerData{
|
||||
Name: strPtr("my-app"),
|
||||
Type: appconfig.InstallerTypeGitHubRelease,
|
||||
BinName: &binName,
|
||||
}
|
||||
installer := newTestGitHubReleaseInstaller(data)
|
||||
assert.Equal(t, "custom-bin", installer.GetArchiveBinName())
|
||||
})
|
||||
|
||||
t.Run("falls back to name when neither set", func(t *testing.T) {
|
||||
data := &appconfig.InstallerData{
|
||||
Name: strPtr("my-app"),
|
||||
Type: appconfig.InstallerTypeGitHubRelease,
|
||||
}
|
||||
installer := newTestGitHubReleaseInstaller(data)
|
||||
assert.Equal(t, "my-app", installer.GetArchiveBinName())
|
||||
})
|
||||
}
|
||||
|
||||
func TestGitHubReleaseGetFilename(t *testing.T) {
|
||||
logger.InitLogger(false)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user