From 67510372ee2de85fba97309edab4c6fbcb2c1227 Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Sat, 25 Feb 2023 21:00:23 +0000 Subject: [PATCH] build(mage): update downloadForgejo target - refactor the downloadForgejo logic - add a step to validate the binary's digest --- magefiles/data/forgejo.json | 19 ---- magefiles/download_forgejo.go | 164 +++++++++++++++----------------- magefiles/forgejo/download.json | 21 ++++ magefiles/mage.go | 2 +- 4 files changed, 101 insertions(+), 105 deletions(-) delete mode 100644 magefiles/data/forgejo.json create mode 100644 magefiles/forgejo/download.json diff --git a/magefiles/data/forgejo.json b/magefiles/data/forgejo.json deleted file mode 100644 index 9741a60..0000000 --- a/magefiles/data/forgejo.json +++ /dev/null @@ -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" - } -} diff --git a/magefiles/download_forgejo.go b/magefiles/download_forgejo.go index 0eeaf3e..384a519 100644 --- a/magefiles/download_forgejo.go +++ b/magefiles/download_forgejo.go @@ -13,11 +13,21 @@ import ( "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 ( - forgejoDownloadFileFormat string = "forgejo-%s-linux-amd64" - forgejoBinariesJson string = "./magefiles/data/forgejo.json" + forgejoBinaryFileFormat string = "forgejo-%s-linux-amd64" + forgejoDigestExtension string = ".sha256" + forgejoSignatureExtension string = ".asc" + forgejoDownloadJson string = "./magefiles/forgejo/download.json" ) func downloadForgejo(version string) error { @@ -29,8 +39,10 @@ func downloadForgejo(version string) error { binaryPath := filepath.Join( downloadFolder, - fmt.Sprintf(forgejoDownloadFileFormat, version), + fmt.Sprintf(forgejoBinaryFileFormat, version), ) + signaturePath := binaryPath + forgejoSignatureExtension + digestPath := binaryPath + forgejoDigestExtension _, err := os.Stat(binaryPath) if err == nil { @@ -38,111 +50,93 @@ func downloadForgejo(version string) error { return nil } - m, err := newForgejoDownloadMap() + data, err := newForgejoDownloadData() if err != nil { return err } - binary, err := os.Create(binaryPath) - if err != nil { - return err - } - defer binary.Close() - - client := http.Client{ - CheckRedirect: func(r *http.Request, _ []*http.Request) error { - r.URL.Opaque = r.URL.Path - return nil + downloads := []struct { + url string + path string + }{ + { + url: data.Downloads[version].Binary, + path: binaryPath, + }, + { + url: data.Downloads[version].Signature, + path: signaturePath, + }, + { + url: data.Downloads[version].Digest, + path: digestPath, }, } - binaryURL := m[version]["binary"] + 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() - resp, err := client.Get(binaryURL) - if err != nil { - return err - } - defer resp.Body.Close() + client := http.Client{ + CheckRedirect: func(r *http.Request, _ []*http.Request) error { + r.URL.Opaque = r.URL.Path + return nil + }, + } - size, err := io.Copy(binary, resp.Body) - if err != nil { - return err + resp, err := client.Get(v.url) + if err != nil { + return err + } + defer resp.Body.Close() + + size, err := io.Copy(download, resp.Body) + if err != nil { + return err + } + + fmt.Printf("Downloaded %s with size %d.\n", v.path, size) + + return nil + }(); err != nil { + return err + } } - fmt.Printf("Downloaded %s with size %d.\n", binaryPath, 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 - } - - 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 - } - 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) } + 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 } -func newForgejoDownloadMap() (forgejoDownload, error) { - m := make(forgejoDownload) +func newForgejoDownloadData() (forgejoDownload, error) { + var data forgejoDownload - f, err := os.Open(forgejoBinariesJson) + f, err := os.Open(forgejoDownloadJson) if err != nil { - return nil, err + return data, err } defer f.Close() decoder := json.NewDecoder(f) - if err = decoder.Decode(&m); err != nil { - return nil, err + if err = decoder.Decode(&data); err != nil { + return data, err } - return m, nil + return data, nil } diff --git a/magefiles/forgejo/download.json b/magefiles/forgejo/download.json new file mode 100644 index 0000000..87b9ce2 --- /dev/null +++ b/magefiles/forgejo/download.json @@ -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" + } + } +} diff --git a/magefiles/mage.go b/magefiles/mage.go index 8ed2c3a..3fe9045 100644 --- a/magefiles/mage.go +++ b/magefiles/mage.go @@ -48,7 +48,7 @@ func DownloadForgejo() error { version := cfg.Forgejo.Version 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