feat: releases from GitHub first, then git.kebcloud.no; releases sets others
CI / Checks (pull_request) Successful in 26s
PR title / Conventional title (pull_request) Successful in 2s

Updates and install.sh try the GitHub mirror, then git.kebcloud.no,
each with a short timeout, and download from the first server with the
release, checked against its checksums.txt. The releases config option
(and LAZYSECRETS_RELEASES for install.sh) lists other servers. The
release workflow copies each release to GitHub when GH_RELEASE_TOKEN is
set. The status pane's issues link points to GitHub.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kebandClaude Opus 5.5 committed 2026-10-12 14:01:51 +02:00
1 parent c00f4b14c4
commit b3c1911ba5
13 files changed
+329 -70

No files matched your search

+10
View File
@@ -14,6 +14,7 @@ import (
"go.yaml.in/yaml/v3"
"git.kebcloud.no/keb/lazysecrets/internal/commands"
"git.kebcloud.no/keb/lazysecrets/internal/update"
)
type Config struct {
@@ -40,6 +41,10 @@ type Config struct {
// background; defaults to true. U and lazysecrets update work either
// way.
UpdateCheck *bool `yaml:"updateCheck"`
// Releases are the repositories updates come from, tried in order:
// on GitHub, or a Gitea or Forgejo server. Defaults to GitHub, then
// git.kebcloud.no (update.DefaultServers).
Releases []string `yaml:"releases"`
// Cache keeps what was loaded (never values) between runs, so lists
// show at once and refresh in the background; defaults to true.
Cache *bool `yaml:"cache"`
@@ -211,6 +216,11 @@ func (c Config) validate(path string) error {
if d := c.LoadDelay; d != nil && (*d < 0 || *d > 5*time.Second) {
return fmt.Errorf("%s: loadDelay: %s is not between 0s and 5s", path, *d)
}
for i, r := range c.Releases {
if _, err := update.API(r); err != nil || !strings.HasPrefix(r, "https://") {
return fmt.Errorf("%s: releases[%d]: %q is not an https:// repository address, like %s", path, i, r, update.GitHubRepo)
}
}
for i, v := range c.Providers.Azure.Vaults {
if !strings.HasPrefix(v, "https://") {
return fmt.Errorf("%s: providers.azure.vaults[%d]: %q is not an https:// vault URL", path, i, v)
+9
View File
@@ -70,6 +70,8 @@ func TestLoadRejectsMistakes(t *testing.T) {
"old layout": "azure:\n vaults: [https://kv.vault.azure.net/]\n",
"duration": "timeout: soon\n",
"view": "sourcesView: tree\n",
"releases": "releases: [git.example.com/team/lazysecrets]\n",
"http": "releases: [http://git.example.com/team/lazysecrets]\n",
} {
if _, err := Load(write(t, content)); err == nil {
t.Errorf("%s: no error", name)
@@ -113,6 +115,13 @@ theme:
}
}
func TestReleases(t *testing.T) {
c, err := Load(write(t, "releases: [https://git.example.com/team/lazysecrets]\n"))
if err != nil || len(c.Releases) != 1 {
t.Errorf("releases = %v, %v", c.Releases, err)
}
}
func TestLoadDelay(t *testing.T) {
c, err := Load(write(t, "loadDelay: 300ms\n"))
if err != nil || c.LoadDelay == nil || *c.LoadDelay != 300*time.Millisecond {