Dan Anglin
7937ecd50b
Upgrade Forgejo to v1.20.4-1 Also the URLs for the Forgejo files is now nicely formatted so the JSON file for the Forgejo downloads is no longer needed and has been removed.
322 lines
7.5 KiB
Go
322 lines
7.5 KiB
Go
//go:build mage
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/magefile/mage/sh"
|
|
)
|
|
|
|
// Download downloads the binaries for a given service.
|
|
func Download(environment, name string) error {
|
|
cfg, err := newConfig(environment)
|
|
if err != nil {
|
|
return fmt.Errorf("unable to load the configuration; %v", err)
|
|
}
|
|
|
|
switch name {
|
|
case "forgejo":
|
|
if err := downloadForgejo(environment, cfg.Forgejo.Version); err != nil {
|
|
return fmt.Errorf("an error occurred whilst getting the forgejo binary; %w", err)
|
|
}
|
|
case "gotosocial":
|
|
if err := downloadGoToSocial(environment, cfg.GoToSocial.Version); err != nil {
|
|
return fmt.Errorf("an error occurred whilst getting the packages for GoToSocial; %w", err)
|
|
}
|
|
case "woodpecker":
|
|
if err := downloadWoodpecker(environment, cfg.Woodpecker.Version); err != nil {
|
|
return fmt.Errorf("an error occurred whilst getting the packages for Woodpecker; %w", err)
|
|
}
|
|
default:
|
|
fmt.Printf("There's no files to download for %q.\n", name)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// downloadWoodpecker downloads and validates the files for the Woodpecker deployment.
|
|
func downloadWoodpecker(environment, version string) error {
|
|
destinationDir := filepath.Join(rootBuildDir, environment, "woodpecker")
|
|
|
|
binaryTarUrl := fmt.Sprintf(
|
|
"https://github.com/woodpecker-ci/woodpecker/releases/download/v%s/woodpecker-server_linux_amd64.tar.gz",
|
|
version,
|
|
)
|
|
|
|
binaryTarFilepath := filepath.Join(
|
|
destinationDir,
|
|
fmt.Sprintf("woodpecker-server-%s_linux_amd64.tar.gz", version),
|
|
)
|
|
|
|
checksumUrl := fmt.Sprintf(
|
|
"https://github.com/woodpecker-ci/woodpecker/releases/download/v%s/checksums.txt",
|
|
version,
|
|
)
|
|
|
|
checksumFilePath := filepath.Join(
|
|
destinationDir,
|
|
fmt.Sprintf("woodpecker_%s_checksums.txt", version),
|
|
)
|
|
|
|
pack := downloadPack{
|
|
destinationDir: destinationDir,
|
|
packages: []pack{
|
|
{
|
|
file: object{
|
|
source: binaryTarUrl,
|
|
destination: binaryTarFilepath,
|
|
},
|
|
},
|
|
},
|
|
validateGPGSignature: false,
|
|
checksum: object{
|
|
source: checksumUrl,
|
|
destination: checksumFilePath,
|
|
},
|
|
validateChecksum: false,
|
|
}
|
|
|
|
if err := download(pack); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// downloadForgejo downloads and validates the Forgejo files.
|
|
func downloadForgejo(environment, version string) error {
|
|
var (
|
|
forgejoBinaryFileFormat = "forgejo-%s-linux-amd64"
|
|
forgejoDigestExtension = ".sha256"
|
|
forgejoSignatureExtension = ".asc"
|
|
)
|
|
|
|
destinationDir := filepath.Join(rootBuildDir, environment, "forgejo")
|
|
|
|
binaryUrl := fmt.Sprintf(
|
|
"https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64",
|
|
version,
|
|
version,
|
|
)
|
|
|
|
binaryPath := filepath.Join(
|
|
destinationDir,
|
|
fmt.Sprintf(forgejoBinaryFileFormat, version),
|
|
)
|
|
|
|
signatureUrl := fmt.Sprintf(
|
|
"https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64.asc",
|
|
version,
|
|
version,
|
|
)
|
|
|
|
signaturePath := binaryPath + forgejoSignatureExtension
|
|
|
|
checksumUrl := fmt.Sprintf(
|
|
"https://codeberg.org/forgejo/forgejo/releases/download/v%s/forgejo-%s-linux-amd64.sha256",
|
|
version,
|
|
version,
|
|
)
|
|
|
|
checksumPath := binaryPath + forgejoDigestExtension
|
|
|
|
pack := downloadPack{
|
|
destinationDir: destinationDir,
|
|
packages: []pack{
|
|
{
|
|
file: object{
|
|
source: binaryUrl,
|
|
destination: binaryPath,
|
|
},
|
|
gpgSignature: object{
|
|
source: signatureUrl,
|
|
destination: signaturePath,
|
|
},
|
|
},
|
|
},
|
|
validateGPGSignature: true,
|
|
checksum: object{
|
|
source: checksumUrl,
|
|
destination: checksumPath,
|
|
},
|
|
validateChecksum: true,
|
|
}
|
|
|
|
if err := download(pack); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// downloadGoToSocial downloads and validates the files for GoToSocial.
|
|
func downloadGoToSocial(environment, version string) error {
|
|
destinationDir := filepath.Join(rootBuildDir, environment, "gotosocial")
|
|
|
|
binaryTarUrl := fmt.Sprintf(
|
|
"https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/gotosocial_%s_linux_amd64.tar.gz",
|
|
version,
|
|
version,
|
|
)
|
|
binaryTarFilepath := filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_linux_amd64.tar.gz", version))
|
|
|
|
webAssetsTarUrl := fmt.Sprintf(
|
|
"https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/gotosocial_%s_web-assets.tar.gz",
|
|
version,
|
|
version,
|
|
)
|
|
webAssetsFilepath := filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_web-assets.tar.gz", version))
|
|
|
|
checksumUrl := fmt.Sprintf(
|
|
"https://github.com/superseriousbusiness/gotosocial/releases/download/v%s/checksums.txt",
|
|
version,
|
|
)
|
|
checksumFilePath := filepath.Join(destinationDir, fmt.Sprintf("gotosocial_%s_checksums.txt", version))
|
|
|
|
pack := downloadPack{
|
|
destinationDir: destinationDir,
|
|
packages: []pack{
|
|
{
|
|
file: object{
|
|
source: binaryTarUrl,
|
|
destination: binaryTarFilepath,
|
|
},
|
|
},
|
|
{
|
|
file: object{
|
|
source: webAssetsTarUrl,
|
|
destination: webAssetsFilepath,
|
|
},
|
|
},
|
|
},
|
|
validateGPGSignature: false,
|
|
checksum: object{
|
|
source: checksumUrl,
|
|
destination: checksumFilePath,
|
|
},
|
|
validateChecksum: true,
|
|
}
|
|
|
|
if err := download(pack); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type downloadPack struct {
|
|
destinationDir string
|
|
packages []pack
|
|
checksum object
|
|
validateGPGSignature bool
|
|
validateChecksum bool
|
|
}
|
|
|
|
type pack struct {
|
|
file object
|
|
gpgSignature object
|
|
}
|
|
|
|
type object struct {
|
|
source string
|
|
destination string
|
|
}
|
|
|
|
// download downloads all the files in the download pack,
|
|
// verifies all the GPG signatures (if enabled) and
|
|
// verifies the checksums (if enabled).
|
|
func download(pack downloadPack) error {
|
|
if err := os.MkdirAll(pack.destinationDir, 0o750); err != nil {
|
|
return fmt.Errorf("unable to make '%s'; %w", pack.destinationDir, err)
|
|
}
|
|
|
|
var objects []object
|
|
|
|
for i := range pack.packages {
|
|
objects = append(objects, pack.packages[i].file)
|
|
if pack.validateGPGSignature {
|
|
objects = append(objects, pack.packages[i].gpgSignature)
|
|
}
|
|
}
|
|
|
|
if pack.validateChecksum {
|
|
objects = append(objects, pack.checksum)
|
|
}
|
|
|
|
for _, object := range objects {
|
|
if err := func() error {
|
|
_, err := os.Stat(object.destination)
|
|
if err == nil {
|
|
fmt.Printf("%s is already downloaded.\n", object.destination)
|
|
return nil
|
|
}
|
|
|
|
file, err := os.Create(object.destination)
|
|
if err != nil {
|
|
return fmt.Errorf("unable to create %s; %w", object.destination, err)
|
|
}
|
|
defer file.Close()
|
|
|
|
client := http.Client{
|
|
CheckRedirect: func(r *http.Request, _ []*http.Request) error {
|
|
r.URL.Opaque = r.URL.Path
|
|
return nil
|
|
},
|
|
}
|
|
|
|
resp, err := client.Get(object.source)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
size, err := io.Copy(file, resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Downloaded %s with size %d.\n", object.destination, size)
|
|
|
|
return nil
|
|
}(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if pack.validateGPGSignature {
|
|
for i := range pack.packages {
|
|
if err := sh.Run("gpg", "--verify", pack.packages[i].gpgSignature.destination, pack.packages[i].file.destination); err != nil {
|
|
return fmt.Errorf("GPG verification failed for '%s'; %w", pack.packages[i].file.destination, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
if pack.validateChecksum {
|
|
startDir, err := os.Getwd()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.Chdir(pack.destinationDir); err != nil {
|
|
return err
|
|
}
|
|
|
|
checksum := filepath.Base(pack.checksum.destination)
|
|
|
|
if err := sh.Run("sha256sum", "--check", "--ignore-missing", checksum); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.Chdir(startDir); err != nil {
|
|
return err
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|