build(mage): update downloadForgejo target

- refactor the downloadForgejo logic
- add a step to validate the binary's digest
This commit is contained in:
Dan Anglin 2023-02-25 21:00:23 +00:00
parent 8000ae308c
commit 67510372ee
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
4 changed files with 101 additions and 105 deletions

View file

@ -1,19 +0,0 @@
{
"1.18.5-0": {
"binary": "https://codeberg.org/attachments/415526b5-e483-45b6-9d46-a7078dcea461",
"signature": "https://codeberg.org/attachments/25cbf994-c045-4252-8c4f-34285d8905a1",
"shasum": "https://codeberg.org/attachments/79192b70-4bcf-4250-94e7-21085f04dd87"
},
"1.18.3-2": {
"binary": "https://codeberg.org/attachments/fd085cac-e462-413c-ab01-a1f36f6c1d24",
"signature": "https://codeberg.org/attachments/a2c9b445-3077-4991-b616-50ddb2e12699"
},
"1.18.3-1": {
"binary": "https://codeberg.org/attachments/be5952ea-6cfb-4be5-a593-3564c4bd8cc9",
"signature": "https://codeberg.org/attachments/07685af6-ca06-4626-8028-302c83ee041c"
},
"1.18.3-0": {
"binary": "https://codeberg.org/attachments/af34fbfc-d651-41b1-aaff-2b9cc7134051",
"signature": "https://codeberg.org/attachments/f064c1a9-66f7-41a9-be03-4dc5e2298370"
}
}

View file

@ -13,11 +13,21 @@ import (
"github.com/magefile/mage/sh" "github.com/magefile/mage/sh"
) )
type forgejoDownload map[string]map[string]string type forgejoDownload struct {
Downloads map[string]forgejoFiles `json:"downloads"`
}
type forgejoFiles struct {
Binary string `json:"binary"`
Signature string `json:"signature"`
Digest string `json:"digest"`
}
const ( const (
forgejoDownloadFileFormat string = "forgejo-%s-linux-amd64" forgejoBinaryFileFormat string = "forgejo-%s-linux-amd64"
forgejoBinariesJson string = "./magefiles/data/forgejo.json" forgejoDigestExtension string = ".sha256"
forgejoSignatureExtension string = ".asc"
forgejoDownloadJson string = "./magefiles/forgejo/download.json"
) )
func downloadForgejo(version string) error { func downloadForgejo(version string) error {
@ -29,8 +39,10 @@ func downloadForgejo(version string) error {
binaryPath := filepath.Join( binaryPath := filepath.Join(
downloadFolder, downloadFolder,
fmt.Sprintf(forgejoDownloadFileFormat, version), fmt.Sprintf(forgejoBinaryFileFormat, version),
) )
signaturePath := binaryPath + forgejoSignatureExtension
digestPath := binaryPath + forgejoDigestExtension
_, err := os.Stat(binaryPath) _, err := os.Stat(binaryPath)
if err == nil { if err == nil {
@ -38,16 +50,36 @@ func downloadForgejo(version string) error {
return nil return nil
} }
m, err := newForgejoDownloadMap() data, err := newForgejoDownloadData()
if err != nil { if err != nil {
return err return err
} }
binary, err := os.Create(binaryPath) downloads := []struct {
if err != nil { url string
return err path string
}{
{
url: data.Downloads[version].Binary,
path: binaryPath,
},
{
url: data.Downloads[version].Signature,
path: signaturePath,
},
{
url: data.Downloads[version].Digest,
path: digestPath,
},
} }
defer binary.Close()
for _, v := range downloads {
if err := func() error {
download, err := os.Create(v.path)
if err != nil {
return fmt.Errorf("unable to create %s; %w", v.path, err)
}
defer download.Close()
client := http.Client{ client := http.Client{
CheckRedirect: func(r *http.Request, _ []*http.Request) error { CheckRedirect: func(r *http.Request, _ []*http.Request) error {
@ -56,93 +88,55 @@ func downloadForgejo(version string) error {
}, },
} }
binaryURL := m[version]["binary"] resp, err := client.Get(v.url)
resp, err := client.Get(binaryURL)
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
size, err := io.Copy(binary, resp.Body) size, err := io.Copy(download, resp.Body)
if err != nil { if err != nil {
return err return err
} }
fmt.Printf("Downloaded %s with size %d.\n", binaryPath, size) fmt.Printf("Downloaded %s with size %d.\n", v.path, size)
signaturePath := binaryPath + ".asc"
signature, err := os.Create(signaturePath)
if err != nil {
return err
}
defer signature.Close()
signatureURL := m[version]["signature"]
sigResp, err := client.Get(signatureURL)
if err != nil {
return err
}
defer sigResp.Body.Close()
size, err = io.Copy(signature, sigResp.Body)
if err != nil {
return nil return nil
} }(); err != nil {
fmt.Printf("Downloaded %s with size %d.\n", signaturePath, size)
shasumPath := binaryPath + ".sha256"
shasum, err := os.Create(shasumPath)
if err != nil {
return fmt.Errorf("unable to create %s; %w", shasumPath, err)
}
defer shasum.Close()
shasumURL := m[version]["shasum"]
shasumResp, err := client.Get(shasumURL)
if err != nil {
return err return err
} }
defer shasumResp.Body.Close()
size, err = io.Copy(shasum, shasumResp.Body)
if err != nil {
return nil
} }
fmt.Printf("Downloaded %s with size %d.\n", shasumPath, size) if err = sh.Run("gpg", "--verify", signaturePath, binaryPath); err != nil {
if err = sh.Run(
"gpg",
"--verify",
signaturePath,
binaryPath,
); err != nil {
return fmt.Errorf("GPG verification failed; %w", err) return fmt.Errorf("GPG verification failed; %w", err)
} }
err = os.Chdir(downloadFolder)
if err != nil {
return err
}
if err := sh.Run("sha256sum", "--check", fmt.Sprintf(forgejoBinaryFileFormat+forgejoDigestExtension, version)); err != nil {
return err
}
return nil return nil
} }
func newForgejoDownloadMap() (forgejoDownload, error) { func newForgejoDownloadData() (forgejoDownload, error) {
m := make(forgejoDownload) var data forgejoDownload
f, err := os.Open(forgejoBinariesJson) f, err := os.Open(forgejoDownloadJson)
if err != nil { if err != nil {
return nil, err return data, err
} }
defer f.Close() defer f.Close()
decoder := json.NewDecoder(f) decoder := json.NewDecoder(f)
if err = decoder.Decode(&m); err != nil { if err = decoder.Decode(&data); err != nil {
return nil, err return data, err
} }
return m, nil return data, nil
} }

View file

@ -0,0 +1,21 @@
{
"downloads": {
"1.18.5-0": {
"binary": "https://codeberg.org/attachments/415526b5-e483-45b6-9d46-a7078dcea461",
"signature": "https://codeberg.org/attachments/25cbf994-c045-4252-8c4f-34285d8905a1",
"digest": "https://codeberg.org/attachments/79192b70-4bcf-4250-94e7-21085f04dd87"
},
"1.18.3-2": {
"binary": "https://codeberg.org/attachments/fd085cac-e462-413c-ab01-a1f36f6c1d24",
"signature": "https://codeberg.org/attachments/a2c9b445-3077-4991-b616-50ddb2e12699"
},
"1.18.3-1": {
"binary": "https://codeberg.org/attachments/be5952ea-6cfb-4be5-a593-3564c4bd8cc9",
"signature": "https://codeberg.org/attachments/07685af6-ca06-4626-8028-302c83ee041c"
},
"1.18.3-0": {
"binary": "https://codeberg.org/attachments/af34fbfc-d651-41b1-aaff-2b9cc7134051",
"signature": "https://codeberg.org/attachments/f064c1a9-66f7-41a9-be03-4dc5e2298370"
}
}
}

View file

@ -48,7 +48,7 @@ func DownloadForgejo() error {
version := cfg.Forgejo.Version version := cfg.Forgejo.Version
if err := downloadForgejo(version); err != nil { if err := downloadForgejo(version); err != nil {
return fmt.Errorf("unable to download Forgejo %s; %w", version, err) return fmt.Errorf("an error occurred whilst getting the forgejo binary; %w", err)
} }
return nil return nil