Skip to content

Commit f4a7254

Browse files
authored
Merge pull request #90 from algorandfoundation/v1.1.0
release: v1.1.0
2 parents 51b8e76 + a5bcf50 commit f4a7254

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1337
-1088
lines changed

.DS_Store

6 KB
Binary file not shown.

.github/workflows/CD.yaml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,24 @@ jobs:
1919
- uses: actions/checkout@v4
2020
- name: Install dependencies
2121
run: go get .
22+
- uses: go-semantic-release/action@v1
23+
name: release
24+
id: semver
25+
with:
26+
dry: true
27+
github-token: ${{ secrets.GITHUB_TOKEN }}
28+
- name: Add version to env
29+
run: echo "VERSION=${{ steps.semver.outputs.version }}" >> $GITHUB_ENV
2230
- name: Build
2331
env:
2432
GOOS: ${{matrix.goos}}
2533
GOARCH: ${{matrix.goarch}}
2634
CGO_ENABLED: 0
27-
run: go build -o bin/algorun-${{matrix.goarch}}-${{matrix.goos}} *.go
35+
run: go build -ldflags "-X main.version=${VERSION}" -o bin/nodekit-${{matrix.goarch}}-${{matrix.goos}} *.go
2836
- uses: actions/upload-artifact@master
2937
with:
30-
name: algorun-${{matrix.goarch}}-${{matrix.goos}}
31-
path: bin/algorun-${{matrix.goarch}}-${{matrix.goos}}
38+
name: nodekit-${{matrix.goarch}}-${{matrix.goos}}
39+
path: bin/nodekit-${{matrix.goarch}}-${{matrix.goos}}
3240
release:
3341
needs:
3442
- build
@@ -37,7 +45,7 @@ jobs:
3745
- uses: actions/checkout@v4
3846
- uses: actions/download-artifact@v4
3947
with:
40-
pattern: algorun*
48+
pattern: nodekit*
4149
path: ./bin
4250
- uses: go-semantic-release/action@v1
4351
name: release
@@ -47,4 +55,4 @@ jobs:
4755
- name: Upload Release
4856
env:
4957
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50-
run: gh release upload v${{steps.semver.outputs.version}} bin/**/*
58+
run: gh release upload v${{steps.semver.outputs.version}} bin/**/*

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
VERSION ?= dev
2+
3+
.PHONY: all
4+
15
build:
2-
CGO_ENABLED=0 go build -o bin/nodekit .
6+
CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION}" -o bin/nodekit .
37
test:
48
go test -coverprofile=coverage.out -coverpkg=./... -covermode=atomic ./...
59
generate:

api/github.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
)
99

1010
const ChannelNotFoundMsg = "channel not found"
11+
const NodeKitReleaseNotFoundMsg = "nodekit release not found"
1112

1213
type GithubVersionResponse struct {
1314
HTTPResponse *http.Response
@@ -66,3 +67,38 @@ func GetGoAlgorandReleaseWithResponse(http HttpPkgInterface, channel string) (*G
6667
versions.JSON200 = *versionResponse
6768
return &versions, nil
6869
}
70+
71+
func GetNodeKitReleaseWithResponse(http HttpPkgInterface) (*GithubVersionResponse, error) {
72+
var versions GithubVersionResponse
73+
resp, err := http.Get("https://api.github.com/repos/algorandfoundation/nodekit/releases/latest")
74+
versions.HTTPResponse = resp
75+
if resp == nil || err != nil {
76+
return nil, err
77+
}
78+
// Update Model
79+
versions.ResponseCode = resp.StatusCode
80+
versions.ResponseStatus = resp.Status
81+
82+
// Exit if not 200
83+
if resp.StatusCode != 200 {
84+
return &versions, nil
85+
}
86+
87+
defer resp.Body.Close()
88+
89+
// Parse the versions to a map
90+
var releaseMap map[string]interface{}
91+
if err = json.NewDecoder(resp.Body).Decode(&releaseMap); err != nil {
92+
return &versions, err
93+
}
94+
95+
version := releaseMap["tag_name"]
96+
97+
if version == nil {
98+
return &versions, errors.New(NodeKitReleaseNotFoundMsg)
99+
}
100+
101+
// Update the JSON200 data and return
102+
versions.JSON200 = strings.Replace(version.(string), "v", "", 1)
103+
return &versions, nil
104+
}

cmd/bootstrap.go

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package cmd
33
import (
44
"context"
55
"fmt"
6+
"time"
7+
68
"github.com/algorandfoundation/nodekit/api"
79
cmdutils "github.com/algorandfoundation/nodekit/cmd/utils"
810
"github.com/algorandfoundation/nodekit/cmd/utils/explanations"
@@ -18,7 +20,6 @@ import (
1820
"github.com/charmbracelet/lipgloss"
1921
"github.com/charmbracelet/log"
2022
"github.com/spf13/cobra"
21-
"time"
2223
)
2324

2425
// bootstrapCmdShort provides a brief description of the "bootstrap" command to initialize a fresh Algorand node.
@@ -40,7 +41,7 @@ var bootstrapCmdLong = lipgloss.JoinVertical(
4041

4142
var tutorial = `# Welcome!
4243
43-
This is the beginning of your adventure into running the an Algorand node!
44+
This is the beginning of your adventure into running an Algorand node!
4445
4546
`
4647

@@ -51,6 +52,17 @@ var bootstrapCmd = &cobra.Command{
5152
Long: bootstrapCmdLong,
5253
SilenceUsage: true,
5354
RunE: func(cmd *cobra.Command, args []string) error {
55+
// Exit the application in an invalid state
56+
if algod.IsInstalled() && !algod.IsService() {
57+
dataDir, _ := algod.GetDataDir("")
58+
if dataDir == "" {
59+
dataDir = "<Path to data directory>"
60+
}
61+
log.Warn("algorand is installed, but not running as a service. Continue at your own risk!")
62+
log.Warn(fmt.Sprintf("try connecting to the node with: ./nodekit -d %s", dataDir))
63+
log.Fatal("invalid state, exiting")
64+
}
65+
5466
ctx := context.Background()
5567
httpPkg := new(api.HttpPkg)
5668
r, _ := glamour.NewTermRenderer(
@@ -84,23 +96,36 @@ var bootstrapCmd = &cobra.Command{
8496
if _, err := p.Run(); err != nil {
8597
log.Fatal(err)
8698
}
99+
87100
if msg == nil {
88101
return nil
89102
}
90103

91-
log.Warn(style.Yellow.Render(explanations.SudoWarningMsg))
92-
if msg.Install && !algod.IsInstalled() {
104+
if msg.Install {
105+
log.Warn(style.Yellow.Render(explanations.SudoWarningMsg))
106+
93107
err := algod.Install()
94108
if err != nil {
95109
return err
96110
}
97-
}
98111

99-
// Wait for algod
100-
time.Sleep(10 * time.Second)
112+
// Wait for algod
113+
time.Sleep(10 * time.Second)
101114

102-
if !algod.IsRunning() {
103-
log.Fatal("algod is not running")
115+
if !algod.IsRunning() {
116+
log.Fatal("algod is not running. Something went wrong with installation")
117+
}
118+
} else {
119+
if !algod.IsRunning() {
120+
log.Info(style.Green.Render("Starting Algod 🚀"))
121+
log.Warn(style.Yellow.Render(explanations.SudoWarningMsg))
122+
err := algod.Start()
123+
if err != nil {
124+
log.Fatal(err)
125+
}
126+
log.Info(style.Green.Render("Algorand started successfully 🎉"))
127+
time.Sleep(2 * time.Second)
128+
}
104129
}
105130

106131
dataDir, err := algod.GetDataDir("")
@@ -114,7 +139,6 @@ var bootstrapCmd = &cobra.Command{
114139
}
115140

116141
if msg.Catchup {
117-
118142
network, err := utils.GetNetworkFromDataDir(dataDir)
119143
if err != nil {
120144
return err

cmd/configure/configure.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func configureNode() error {
5555

5656
// Check systemctl first
5757
if algod.IsService() {
58-
if promptWrapperYes("Algorand is installed as a service. Do you wish to edit the service file to change the data directory? (y/n)") {
58+
if promptWrapperYes("Algorand is installed as a service. Do you wish to edit the service file to change the data directory? (y/N)") {
5959
// Edit the service file with the user's new data directory
6060
systemServiceConfigure = true
6161
} else {
@@ -84,18 +84,18 @@ func configureNode() error {
8484
fmt.Println("Found valid Algorand Data Directory: " + algorandData)
8585

8686
if systemServiceConfigure {
87-
if promptWrapperYes("Would you like to set the ALGORAND_DATA env variable as the data directory for the systemd Algorand service? (y/n)") {
87+
if promptWrapperYes("Would you like to set the ALGORAND_DATA env variable as the data directory for the systemd Algorand service? (y/N)") {
8888
editAlgorandServiceFile(algorandData)
8989
os.Exit(0)
9090
}
9191
}
9292

93-
if promptWrapperNo("Do you want to set a completely new data directory? (y/n)") {
93+
if promptWrapperNo("Do you want to set a completely new data directory? (y/N)") {
9494
fmt.Println("User chose not to set a completely new data directory.")
9595
os.Exit(0)
9696
}
9797

98-
if promptWrapperYes("Do you want to manually input the new data directory? (y/n)") {
98+
if promptWrapperYes("Do you want to manually input the new data directory? (y/N)") {
9999
newPath := promptWrapperInput("Enter the new data directory path")
100100

101101
if !validateAlgorandDataDir(newPath) {
@@ -130,7 +130,7 @@ func configureNode() error {
130130
}
131131

132132
if len(paths) == 1 {
133-
if promptWrapperYes("Do you want to set this directory as the new data directory? (y/n)") {
133+
if promptWrapperYes("Do you want to set this directory as the new data directory? (y/N)") {
134134
if systemServiceConfigure {
135135
// Edit the service file
136136
editAlgorandServiceFile(paths[0])
@@ -142,7 +142,7 @@ func configureNode() error {
142142

143143
} else {
144144

145-
if promptWrapperYes("Do you want to set one of these directories as the new data directory? (y/n)") {
145+
if promptWrapperYes("Do you want to set one of these directories as the new data directory? (y/N)") {
146146

147147
selectedPath := promptWrapperSelection("Select an Algorand data directory", paths)
148148

@@ -158,12 +158,12 @@ func configureNode() error {
158158
}
159159

160160
// Deep search
161-
if promptWrapperNo("Do you want NodeKit to do a deep search for pre-existing Algorand Data directories? (y/n)") {
162-
fmt.Println("User chose not to search for more pre-existing Algorand Data directories. Exiting...")
161+
if promptWrapperNo("Do you want NodeKit to do a deep search for pre-existing Algorand data directories? (y/N)") {
162+
fmt.Println("User chose not to search for more pre-existing Algorand data directories. Exiting...")
163163
os.Exit(0)
164164
}
165165

166-
fmt.Println("Searching for pre-existing Algorand Data directories in HOME directory...")
166+
fmt.Println("Searching for pre-existing Algorand data directories in HOME directory...")
167167
paths = deepSearchAlgorandDataDirs()
168168

169169
if len(paths) == 0 {

cmd/debug.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ var debugCmd = cmdutils.WithAlgodFlags(&cobra.Command{
7272
return err
7373
}
7474
folderDebug, err := utils.ToDataFolderConfig(dataDir)
75+
folderDebug.Token = folderDebug.Token[:3] + "..."
7576
if err != nil {
7677
return err
7778
}

cmd/root.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cmd
22

33
import (
44
"context"
5+
"fmt"
56
"github.com/algorandfoundation/nodekit/api"
67
"github.com/algorandfoundation/nodekit/cmd/catchup"
78
"github.com/algorandfoundation/nodekit/cmd/configure"
@@ -21,12 +22,11 @@ import (
2122
var (
2223
Name = "nodekit"
2324

25+
NeedsUpgrade = false
26+
2427
// algodEndpoint defines the URI address of the Algorand node, including the protocol (http/https), for client communication.
2528
algodData string
2629

27-
// Version represents the application version string, which is set during build or defaults to "unknown".
28-
Version = ""
29-
3030
// force indicates whether actions should be performed forcefully, bypassing checks or confirmations.
3131
force bool = false
3232

@@ -45,10 +45,9 @@ var (
4545
)
4646
// RootCmd is the primary command for managing Algorand nodes, providing CLI functionality and TUI for interaction.
4747
RootCmd = utils.WithAlgodFlags(&cobra.Command{
48-
Use: Name,
49-
Version: Version,
50-
Short: short,
51-
Long: long,
48+
Use: Name,
49+
Short: short,
50+
Long: long,
5251
CompletionOptions: cobra.CompletionOptions{
5352
DisableDefaultCmd: true,
5453
},
@@ -128,6 +127,7 @@ func NeedsToBeStopped(cmd *cobra.Command, args []string) {
128127
// init initializes the application, setting up logging, commands, and version information.
129128
func init() {
130129
log.SetReportTimestamp(false)
130+
RootCmd.SetVersionTemplate(fmt.Sprintf("nodekit-%s-%s@{{.Version}}\n", runtime.GOARCH, runtime.GOOS))
131131
// Add Commands
132132
if runtime.GOOS != "windows" {
133133
RootCmd.AddCommand(bootstrapCmd)
@@ -143,6 +143,8 @@ func init() {
143143
}
144144

145145
// Execute executes the root command.
146-
func Execute() error {
146+
func Execute(version string, needsUpgrade bool) error {
147+
RootCmd.Version = version
148+
NeedsUpgrade = needsUpgrade
147149
return RootCmd.Execute()
148150
}

cmd/upgrade.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package cmd
22

33
import (
4+
"github.com/algorandfoundation/nodekit/api"
45
"github.com/algorandfoundation/nodekit/cmd/utils/explanations"
56
"github.com/algorandfoundation/nodekit/internal/algod"
7+
"github.com/algorandfoundation/nodekit/internal/system"
68
"github.com/algorandfoundation/nodekit/ui/style"
79
"github.com/charmbracelet/lipgloss"
810
"github.com/charmbracelet/log"
@@ -30,12 +32,19 @@ var upgradeLong = lipgloss.JoinVertical(
3032

3133
// upgradeCmd is a Cobra command used to upgrade Algod, utilizing the OS-specific package manager if applicable.
3234
var upgradeCmd = &cobra.Command{
33-
Use: "upgrade",
34-
Short: upgradeShort,
35-
Long: upgradeLong,
36-
SilenceUsage: true,
37-
PersistentPreRun: NeedsToBeStopped,
35+
Use: "upgrade",
36+
Short: upgradeShort,
37+
Long: upgradeLong,
38+
SilenceUsage: true,
3839
Run: func(cmd *cobra.Command, args []string) {
40+
if NeedsUpgrade {
41+
log.Info(style.Green.Render("Upgrading NodeKit"))
42+
err := system.Upgrade(new(api.HttpPkg))
43+
if err != nil {
44+
log.Fatal(err)
45+
}
46+
}
47+
3948
// TODO: get expected version and check if update is required
4049
log.Info(style.Green.Render(UpgradeMsg))
4150
// Warn user for prompt

docs/.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v20.11.0

0 commit comments

Comments
 (0)