1
- Self-Update library for GitHub/ Gitea hosted applications in Go
1
+ Self-Update library for Github, Gitea and Gitlab hosted applications in Go
2
2
==============================================================
3
3
4
4
[ ![ Godoc reference] ( https://godoc.org/github.com/creativeprojects/go-selfupdate?status.svg )] ( http://godoc.org/github.com/creativeprojects/go-selfupdate )
5
5
[ ![ Build] ( https://github.com/creativeprojects/go-selfupdate/workflows/Build/badge.svg )] ( https://github.com/creativeprojects/go-selfupdate/actions )
6
6
[ ![ codecov] ( https://codecov.io/gh/creativeprojects/go-selfupdate/branch/main/graph/badge.svg?token=3FejM0fkw2 )] ( https://codecov.io/gh/creativeprojects/go-selfupdate )
7
7
8
8
<!-- ts-->
9
- * [ Self\- Update library for GitHub/ Gitea hosted applications in Go] ( #self-update-library-for-githubgitea -hosted-applications-in-go )
9
+ * [ Self\- Update library for Github, Gitea and Gitlab hosted applications in Go] ( #self-update-library-for-github-gitea-and-gitlab -hosted-applications-in-go )
10
10
* [ Introduction] ( #introduction )
11
11
* [ Example] ( #example )
12
- * [ Important note] ( #important-note )
12
+ * [ Upgrade from v0\+ to v1] ( #upgrade-from-v0-to-v1 )
13
+ * [ Repository] ( #repository )
14
+ * [ ParseSlug] ( #parseslug )
15
+ * [ NewRepositorySlug] ( #newrepositoryslug )
16
+ * [ NewRepositoryID (GitLab only)] ( #newrepositoryid-gitlab-only )
17
+ * [ Context] ( #context )
18
+ * [ Package functions] ( #package-functions )
19
+ * [ Methods on Source interface] ( #methods-on-source-interface )
20
+ * [ Methods on Updater struct] ( #methods-on-updater-struct )
13
21
* [ Naming Rules of Released Binaries] ( #naming-rules-of-released-binaries )
14
22
* [ Naming Rules of Versions (=Git Tags)] ( #naming-rules-of-versions-git-tags )
15
23
* [ Structure of Releases] ( #structure-of-releases )
@@ -18,7 +26,9 @@ Self-Update library for GitHub/Gitea hosted applications in Go
18
26
* [ SHA256] ( #sha256 )
19
27
* [ ECDSA] ( #ecdsa )
20
28
* [ Using a single checksum file for all your assets] ( #using-a-single-checksum-file-for-all-your-assets )
21
- * [ Using other providers than Github] ( #using-other-providers-than-github )
29
+ * [ Other providers than Github] ( #other-providers-than-github )
30
+ * [ GitLab] ( #gitlab )
31
+ * [ Example:] ( #example-1 )
22
32
* [ Copyright] ( #copyright )
23
33
24
34
<!-- te-->
@@ -47,7 +57,7 @@ This library started as a fork of https://github.com/rhysd/go-github-selfupdate.
47
57
- able to detect different ARM CPU architectures (the original library wasn't working on my different versions of raspberry pi)
48
58
- support for assets compressed with bzip2 (.bz2)
49
59
- can use a single file containing the sha256 checksums for all the files (one per line)
50
- - separate the provider and the updater, so we can add more providers (GitHub , Gitea, Gitlab, etc.)
60
+ - separate the provider and the updater, so we can add more providers (Github , Gitea, Gitlab, etc.)
51
61
- return well defined wrapped errors that can be checked with ` errors.Is(err error, target error) `
52
62
53
63
# Example
@@ -56,9 +66,9 @@ Here's an example how to use the library for an application to update itself
56
66
57
67
``` go
58
68
func update (version string ) error {
59
- latest , found , err := selfupdate.DetectLatest (" creativeprojects/resticprofile" )
69
+ latest , found , err := selfupdate.DetectLatest (context. Background (), selfupdate. ParseSlug ( " creativeprojects/resticprofile" ) )
60
70
if err != nil {
61
- return fmt.Errorf (" error occurred while detecting version: %v " , err)
71
+ return fmt.Errorf (" error occurred while detecting version: % w " , err)
62
72
}
63
73
if !found {
64
74
return fmt.Errorf (" latest version for %s /%s could not be found from github repository" , runtime.GOOS , runtime.GOARCH )
@@ -73,18 +83,79 @@ func update(version string) error {
73
83
if err != nil {
74
84
return errors.New (" could not locate executable path" )
75
85
}
76
- if err := selfupdate.UpdateTo (latest.AssetURL , latest.AssetName , exe); err != nil {
77
- return fmt.Errorf (" error occurred while updating binary: %v " , err)
86
+ if err := selfupdate.UpdateTo (context. Background (), latest.AssetURL , latest.AssetName , exe); err != nil {
87
+ return fmt.Errorf (" error occurred while updating binary: % w " , err)
78
88
}
79
89
log.Printf (" Successfully updated to version %s " , latest.Version ())
80
90
return nil
81
91
}
82
92
```
83
93
84
- # Important note
94
+ # Upgrade from v0+ to v1
95
+
96
+ Version v1+ has a ** stable** API. It is slightly different from the API of versions 0+.
97
+
98
+ ## Repository
99
+
100
+ Some functions needed a couple ` owner ` /` repo ` and some other a single string called ` slug ` . These have been replaced by a ` Repository ` .
101
+
102
+ Two constructors are available:
103
+
104
+ ### ParseSlug
105
+
106
+ Parses a * slug* string like ` owner/repository_name `
107
+
108
+ ``` go
109
+ func ParseSlug (slug string ) RepositorySlug
110
+ ```
111
+
112
+ ### NewRepositorySlug
113
+
114
+ Creates a repository from both owner and repo strings
115
+
116
+ ```go
117
+ func NewRepositorySlug(owner, repo string) RepositorySlug
118
+ ```
119
+
120
+ ### NewRepositoryID (GitLab only)
121
+
122
+ GitLab can also refer to a repository via its internal ID. This constructor can be used with a numeric repository ID.
123
+
124
+ ```go
125
+ func NewRepositoryID(id int) RepositoryID
126
+ ```
127
+
128
+ ### Context
129
+
130
+ All methods are now accepting a `context` as their first parameter. You can use it to cancel a long running operation.
131
+
132
+ ## Package functions
133
+
134
+ | v0 | v1 |
135
+ |----|----|
136
+ | UpdateTo(assetURL, assetFileName, cmdPath string) error | UpdateTo(ctx context.Context, assetURL, assetFileName, cmdPath string) error |
137
+ | DetectLatest(slug string) (*Release, bool, error) | DetectLatest(ctx context.Context, repository Repository) (*Release, bool, error) |
138
+ | DetectVersion(slug string, version string) (*Release, bool, error) | DetectVersion(ctx context.Context, repository Repository, version string) (*Release, bool, error) |
139
+ | UpdateCommand(cmdPath string, current string, slug string) (*Release, error) | UpdateCommand(ctx context.Context, cmdPath string, current string, repository Repository) (*Release, error) |
140
+ | UpdateSelf(current string, slug string) (*Release, error) | UpdateSelf(ctx context.Context, current string, repository Repository) (*Release, error) |
141
+
142
+ ## Methods on Source interface
143
+
144
+ | v0 | v1 |
145
+ |----|----|
146
+ | ListReleases(owner, repo string) ([]SourceRelease, error) | ListReleases(ctx context.Context, repository Repository) ([]SourceRelease, error) |
147
+ | DownloadReleaseAsset(owner, repo string, releaseID, id int64) (io.ReadCloser, error) | DownloadReleaseAsset(ctx context.Context, rel *Release, assetID int64) (io.ReadCloser, error) |
148
+
149
+ ## Methods on Updater struct
150
+
151
+ | v0 | v1 |
152
+ |----|----|
153
+ | DetectLatest(slug string) (release *Release, found bool, err error) | DetectLatest(ctx context.Context, repository Repository) (release *Release, found bool, err error) |
154
+ | DetectVersion(slug string, version string) (release *Release, found bool, err error) | DetectVersion(ctx context.Context, repository Repository, version string) (release *Release, found bool, err error) |
155
+ | UpdateCommand(cmdPath string, current string, slug string) (*Release, error) | UpdateCommand(ctx context.Context, cmdPath string, current string, repository Repository) (*Release, error) |
156
+ | UpdateSelf(current string, slug string) (*Release, error) | UpdateSelf(ctx context.Context, current string, repository Repository) (*Release, error) |
157
+ | UpdateTo(rel *Release, cmdPath string) error | UpdateTo(ctx context.Context, rel *Release, cmdPath string) error |
85
158
86
- ** The API can change anytime until it reaches version 1.0.**
87
- It is unlikely it will change drastically though, but it can.
88
159
89
160
# Naming Rules of Released Binaries
90
161
@@ -229,14 +300,68 @@ Tools like [goreleaser][] produce a single checksum file for all your assets. A
229
300
updater , _ := NewUpdater (Config{Validator: &ChecksumValidator{UniqueFilename: " checksums.txt" }})
230
301
```
231
302
232
- # Using other providers than Github
303
+ # Other providers than Github
233
304
234
305
This library can be easily extended by providing a new source and release implementation for any git provider
235
306
Currently implemented are
236
307
- Github (default)
237
- - Gitea
308
+ - Gitea
309
+ - Gitlab
238
310
239
- Check the * -custom examples in cmd to see how a custom source like the GiteaSource can be used
311
+ # GitLab
312
+
313
+ Support for GitLab is experimental.
314
+
315
+ To be able to download assets from a private instance of GitLab, you have to publish your files to the [ Generic Package Registry] ( https://docs.gitlab.com/ee/user/packages/package_registry/index.html ) .
316
+
317
+ If you're using goreleaser, you just need to add this option:
318
+
319
+ ``` yaml
320
+ # .goreleaser.yml
321
+ gitlab_urls :
322
+ use_package_registry : true
323
+
324
+ ```
325
+
326
+ See [ goreleaser documentation] ( https://goreleaser.com/scm/gitlab/#generic-package-registry ) for more information.
327
+
328
+ ## Example:
329
+
330
+ ``` go
331
+ func update () {
332
+ source , err := selfupdate.NewGitLabSource (selfupdate.GitLabConfig {
333
+ BaseURL: " https://private.instance.on.gitlab.com/" ,
334
+ })
335
+ if err != nil {
336
+ log.Fatal (err)
337
+ }
338
+ updater , err := selfupdate.NewUpdater (selfupdate.Config {
339
+ Source: source,
340
+ Validator: &selfupdate.ChecksumValidator {UniqueFilename: " checksums.txt" }, // checksum from goreleaser
341
+ })
342
+ if err != nil {
343
+ log.Fatal (err)
344
+ }
345
+ release , found , err := updater.DetectLatest (context.Background (), selfupdate.NewRepositorySlug (" owner" , " cli-tool" ))
346
+ if err != nil {
347
+ log.Fatal (err)
348
+ }
349
+ if !found {
350
+ log.Print (" Release not found" )
351
+ return
352
+ }
353
+ fmt.Printf (" found release %s \n " , release.Version ())
354
+
355
+ exe , err := os.Executable ()
356
+ if err != nil {
357
+ return errors.New (" could not locate executable path" )
358
+ }
359
+ err = updater.UpdateTo (context.Background (), release, exe)
360
+ if err != nil {
361
+ log.Fatal (err)
362
+ }
363
+ }
364
+ ```
240
365
241
366
# Copyright
242
367
0 commit comments