Skip to content

Instantly share code, notes, and snippets.

@abraham-ny
Last active April 10, 2025 11:29
Show Gist options
  • Select an option

  • Save abraham-ny/2cdaf50b908d6926dca73d6e5040972b to your computer and use it in GitHub Desktop.

Select an option

Save abraham-ny/2cdaf50b908d6926dca73d6e5040972b to your computer and use it in GitHub Desktop.
How to check for updates from github in go and download the latest executable
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
)
const (
repoAPIURL = "https://api.github.com/repos/abraham-ny/filestudio/releases/latest"
exeName = "filestudio.exe"
)
type Release struct {
TagName string `json:"tag_name"`
Assets []struct {
Name string `json:"name"`
BrowserDownloadURL string `json:"browser_download_url"`
} `json:"assets"`
}
func main() {
currentVersion := "v1.0.0" // Replace with your current version
latestRelease, err := getLatestRelease()
if err != nil {
fmt.Println("Error fetching latest release:", err)
return
}
if currentVersion != latestRelease.TagName {
fmt.Println("New version available:", latestRelease.TagName)
// Find and download the filestudio.exe from the release assets
for _, asset := range latestRelease.Assets {
if asset.Name == exeName {
err := downloadAndReplaceFile(asset.BrowserDownloadURL, exeName)
if err != nil {
fmt.Println("Error downloading or replacing the file:", err)
} else {
fmt.Println("Updated", exeName, "to version", latestRelease.TagName)
}
return
}
}
fmt.Println(exeName, "not found in the release assets.")
} else {
fmt.Println("You are using the latest version:", currentVersion)
}
}
func getLatestRelease() (*Release, error) {
resp, err := http.Get(repoAPIURL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var release Release
err = json.NewDecoder(resp.Body).Decode(&release)
if err != nil {
return nil, err
}
return &release, nil
}
func downloadAndReplaceFile(url, fileName string) error {
// Download the file
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
tempFileName := fileName + ".tmp"
// Create a temporary file in the same directory
out, err := os.Create(tempFileName)
if err != nil {
return err
}
defer out.Close()
// Write the downloaded content to the temporary file
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
// Close the temporary file
out.Close()
// Remove the existing exe file
err = os.Remove(fileName)
if err != nil {
return err
}
// Rename the temporary file to the original exe name
err = os.Rename(tempFileName, fileName)
if err != nil {
return err
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment