Skip to content

Commit

Permalink
Clean up and updated doc
Browse files Browse the repository at this point in the history
  • Loading branch information
alinz committed Jan 10, 2024
1 parent 798eebc commit 190acf3
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 41 deletions.
28 changes: 22 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
SELF_UPDATE_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SELF_UPDATE_PRIVATE_KEY: ${{ secrets.SELF_UPDATE_PRIVATE_KEY }}
SELF_UPDATE_PUBLIC_KEY: ${{ secrets.SELF_UPDATE_PUBLIC_KEY }}
SELF_UPDATE_VERSION: ${{ github.ref_name }}

steps:
- name: Setup Go 1.21
Expand All @@ -36,17 +37,32 @@ jobs:
- name: Run Unit Tests
run: go test -v ./...

- name: Build cli
- name: Build temporary cli
run: go build -o ./selfupdate ./cmd/selfupdate/main.go

- name: Create a Release
run: |
./selfupdate github release --owner blockthrough --repo selfupdate.go --version ${{ github.ref_name }} --title ${{ github.ref_name }}
./selfupdate github release \
--owner blockthrough \
--repo selfupdate.go \
--version ${{ SELF_UPDATE_VERSION }} \
--title ${{ SELF_UPDATE_VERSION }} \
--token ${{ SELF_UPDATE_GH_TOKEN }}
- name: Build cli for all OS
- name: Build and Sign
run: |
GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} go build -ldflags "-X main.Version=${{ github.ref_name }}" -o ./selfupdate-${{ matrix.os }}-${{ matrix.arch }} ./cmd/selfupdate/main.go
GOOS=${{ matrix.os }} GOARCH=${{ matrix.arch }} \
go build \
-ldflags "-X main.Version=${{ SELF_UPDATE_VERSION }} -X main.PublicKey=${{ SELF_UPDATE_PUBLIC_KEY }}" \
-o ./selfupdate-${{ matrix.os }}-${{ matrix.arch }} \
./cmd/selfupdate/main.go
- name: Release
- name: Upload New Release
run: |
./selfupdate github upload --owner blockthrough --repo selfupdate.go --filename selfupdate-${{ matrix.os }}-${{ matrix.arch }}.sign --version ${{ github.ref_name }} --sign < ./selfupdate-${{ matrix.os }}-${{ matrix.arch }}
./selfupdate github upload \
--owner blockthrough \
--repo selfupdate.go \
--filename selfupdate-${{ matrix.os }}-${{ matrix.arch }}.sign \
--version ${{ SELF_UPDATE_VERSION }} \
--token ${{ SELF_UPDATE_GH_TOKEN }} \
--key ${{ SELF_UPDATE_PRIVATE_KEY }} < ./selfupdate-${{ matrix.os }}-${{ matrix.arch }}
43 changes: 27 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,18 @@ selfupdate crypto keys

#### sign

sign a binary using a private key. The private key must be set using the environment variable `SELF_UPDATE_PRIVATE_KEY`
sign a binary using a private key. The private key must be passed as an argument using `--key`

```bash
export SELF_UPDATE_PRIVATE_KEY=....
selfupdate crypto sign < ./bin/file > ./bin/file.sig
selfupdate crypto sign --key "CONTENT OF PRIVATE KEY" < ./bin/file > ./bin/file.sig
```

#### verify

verify a binary using a public key. The public key must be set using the environment variable `SELF_UPDATE_PUBLIC_KEY`
verify a binary using a public key. The public key must be passed as an argument using `--key`

```bash
export SELF_UPDATE_PUBLIC_KEY=....
selfupdate crypto verify < ./bin/file.sg > ./bin/file
selfupdate crypto verify --key "CONTENT OF PUBLIC KEY" < ./bin/file.sg > ./bin/file
```

### github
Expand All @@ -80,29 +78,27 @@ To provide a better developer experience, this command can create a new github r
> NOTE: running this command with the same version will be noop. So it can be safely used in github actions workflow with matrix strategy.
```bash
selfupdate github release -owner blockthough --repo selfupdate.go --version v0.0.1 --title version v0.0.1 --desc "this is an amazin release"
selfupdate github release -owner blockthough --repo selfupdate.go --token GITHUB_TOKEN --version v0.0.1 --title version v0.0.1 --desc "this is an amazin release"
```

> for more info, run `selfupdate github release --help`
#### upload

upload a new asset to an already created github release. It is a requirement to set an environment variable, `SELF_UPDATE_PRIVATE_KEY`, while using `--sign` flag.

the `--sign` flag will sign the uploaded content which later can be verified using `SELF_UPDATE_PUBLIC_KEY` environment variable.
upload a new asset to an already created github release. If required to sign the binary file prior to upload, provide `--key` with the content of the generated private key.

> In order to upload assets, a github release must be created first. Please refer to `release` subcommand. Also this command can be used multiple times for each individual asset in github actions workflow.
```bash
selfupdate github upload -owner blockthough --repo selfupdate.go --version v0.0.1 --filename selfupload.sign --sign < /path/to/file
selfupdate github upload -owner blockthough --repo selfupdate.go --token GITHUB_TOKEN --version v0.0.1 --filename selfupload.sign --key PRIVATE_KEY < /path/to/file
```

#### download

In order to download a specific asset from a gethub release, this command can be used. It requires `--filename` and `--version` to be presented.

```bash
selfupdate github download -owner blockthough --repo selfupdate.go --version v0.0.1 --filename selfupload.sign --verify > /path/to/file
selfupdate github download -owner blockthough --repo selfupdate.go --version v0.0.1 --filename selfupload.sign --key PUBLIC_KEY > /path/to/file
```

## Usage
Expand All @@ -111,7 +107,7 @@ In order to have successful self-updating binaries, two steps need to be followe

### ( 1 ) Github Actions Workflow

- First compile the your code and generate a binary, make sure to use `-ldflags "-X main.Version=${{ github.ref_name }}"` flag during `go build` to inject the new tag as a version into the binary.
- First compile the your code and generate a binary, make sure to use `-ldflags "-X main.Version=${{ github.ref_name }} -X main.PublicKey=${{ PUBLIC_KEY }}"` flag during `go build` to inject the new tag as a version into the binary.

- Create a new Release using `selfupdate github release` command
- Sign and upload content using `selfupdate github upload`
Expand All @@ -137,24 +133,39 @@ import (


const (
Version = "development"
Version = ""
PublicKey = ""
)

func main() {
// NOTE: please refer to "Create a Fine-Grained Personal Access Tokens" section of doc
ghToken, ok := os.LookupEnv("MY_AWESOME_PROJECT_GITHUB_TOKEN")
if !ok {
// error out that github token is not presented
}

selfupdate.Auto(
context.Background(), // Context
"blockthrough", // Owner Name
"selfupdate.go", // Repo Name
Version, // Current Version
"selfupdate", // Executable Name
"selfupdate", // Executable Name,
ghToken, // Github Token
PublicKey, // Public Key
)

// rest of the program
}
```

`selfupdate.Auto` function automatically checks, downloads, patches and reruns the previously issued commands.
`selfupdate.Auto` function automatically checks, downloads, patches and re-runs the previously issued command.

# Example

`selfupdate` cli is using itself for self-updating. Please refer to both `cmd/selfupdate/main.go` and `.github/workflows/build.yml` files for more info.

# Create a Fine-Grained Personal Access Tokens

Each person who needs to use your app cli and leverage the selfupdating, is required to create a github api token. It is recommended to use the following [Token/Settings](https://github.com/settings/tokens?type=beta) to generate the API keys.

The only required option is to select the project and on `Repository Permissions` select only `Contents` as `Read` access. We only need to read the metadata and download assets during the update, nothing more.
46 changes: 27 additions & 19 deletions cmd/selfupdate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,49 @@ package main

import (
"context"
"fmt"
"log"
"os"

"selfupdate.blockthrough.com"
"selfupdate.blockthrough.com/cmd/selfupdate/commands"
)

// SELF_UPDATE_GH_TOKEN=
// SELF_UPDATE_PRIVATE_KEY=
// SELF_UPDATE_PUBLIC_KEY=

// selfupdate crypto generate-keys
// selfupdate crypto sign < ./bin/btctl > ./bin/btctl.sig
// selfupdate crypto verify < ./bin/btctl.sig > ./bin/btctl
// selfupdate github release --owner blockthrough --repo up-marble --name btctl.sign --version v1.0.0 --sign < ./bin/btctl
// selfupdate github download --owner blockthrough --repo up-marble --name btctl.sign --version v1.0.0 --verify > ./bin/btctl

var Version string = "v0.0.0"
// During the build process, these variables are set by Github Actions
// NOTE: if Version is empty or SELF_UPDATE_GH_TOKEN is not set, selfupdating is disabled
var Version string = ""
var PublicKey string = ""
var GithubToken string = ""

func main() {
runUpdate()

err := commands.Execute(Version)
if err != nil {
log.Fatal("Failed to execute: ", err)
os.Exit(1)
}
}

func runUpdate() {
// In order for selfupdating to work, the following conditions must be met:
// 1. Version must be set
// 2. SELF_UPDATE_GH_TOKEN must be set
// 3. PublicKey must be set
// for setting up the token please refer to
// "Create a Fine-Grained Personal Access Tokens" in README.md
ghToken, ok := os.LookupEnv("SELF_UPDATE_GH_TOKEN")
if !ok {
fmt.Fprintf(os.Stderr, "Warning: SELF_UPDATE_GH_TOKEN env is not set, selfupdating is disabled")
return
}

selfupdate.Auto(
context.Background(), // Context
"blockthrough", // Owner Name
"selfupdate.go", // Repo Name
Version, // Current Version
"selfupdate", // Executable Name,
GithubToken, // Github Token
ghToken, // Github Token
PublicKey, // Public Key
)

err := commands.Execute(Version)
if err != nil {
log.Fatal("Failed to execute: ", err)
os.Exit(1)
}
}

0 comments on commit 190acf3

Please sign in to comment.