Modifying the agent build process to record the name of agent binaries in releases.json

This commit is contained in:
Zack Mullaly 2018-08-20 15:56:22 -04:00
Родитель 5a3aeb1880
Коммит 9b9b28872a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 1486642516ED3535
3 изменённых файлов: 146 добавлений и 128 удалений

Просмотреть файл

@ -1,24 +1,11 @@
{
"agent": {
"latest": "20180807-0.e8eb90a1.prod",
"releases": [
{
"tag": "20180807-0.e8eb90a1.prod",
"date": "2018/8/7",
"notes": "Read the correct ident on CentOS 7",
"sha256": ""
}
]
},
"agentConfig": {
"latest": "20180409-0.e8eb90a.prod",
"releases": [
{
"tag": "20180807-0.e8eb90a1.prod",
"date": "2018/8/7",
"notes": "First release of the snazzy config tool",
"sha256": ""
}
]
}
"agent": {
"latest": "",
"releases": [
]
},
"agentConfig": {
"latest": "",
"releases": []
}
}

Просмотреть файл

@ -1,4 +1,17 @@
BUILDREV=$(date +%Y%m%d)-0.$(git log --pretty=format:'%h' -n 1).prod
RELEASEDIR=releases
TAG=$(date +%Y%m%d)-0.$(git log --pretty=format:'%h' -n 1)
BUILDS=(
# FORMAT
# GOOS GOARCH BINSUFFIX
"darwin 386 darwin-i386-$TAG.prod"
"darwin amd64 darwin-amd64-$TAG.prod"
"linux 386 linux-i386-$TAG.prod"
"linux amd64 linux-amd64-$TAG.prod"
"windows 386 windows-i386-$TAG.prod.exe"
"windows amd64 windows-amd64-$TAG.prod.exe"
)
# update_releases invokes the update_release_json tool to record an agent update.
# It expects to be called with three arguments:
@ -7,16 +20,24 @@ BUILDREV=$(date +%Y%m%d)-0.$(git log --pretty=format:'%h' -n 1).prod
# 3. The path to the new agent binary.
function update_releases() {
releasejson=$(go run tools/update_release_json.go \
-releases $1 \
-releases $RELEASEDIR/$1 \
-component agent \
-tag $2 \
-sha256 $(cat $3 | openssl sha256))
-binary $3 \
-sha256 $(cat $RELEASEDIR/$3 | openssl sha256))
echo "$releasejson" > $1
echo "$releasejson" > $RELEASEDIR/$1
}
GOOS=darwin GOARCH=386 go build -o releases/mig-agent-$BUILDREV github.com/mozilla/mig/mig-agent
if [ $? -eq 0 ]; then
update_releases releases/releases.json $BUILDREV releases/mig-agent-$BUILDREV
fi
for build in "${BUILDS[@]}"; do
IFS=" " read -ra args <<< "$build"
echo "Building an agent for ${args[0]}/${args[1]}"
GOOS=${args[0]} GOARCH=${args[1]} go build -o $RELEASEDIR/mig-agent-${args[2]} github.com/mozilla/mig/mig-agent
if [ $? -eq 0 ]; then
echo "+ Build succeeded"
update_releases releases.json $TAG mig-agent-${args[2]}
else
echo "- Build failed";
fi
done

Просмотреть файл

@ -1,161 +1,171 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"os"
"path"
"strings"
"time"
"encoding/json"
"flag"
"fmt"
"os"
"path"
"strings"
"time"
)
const defaultReleasesDir string = "releases"
const defaultReleasesDir string = "releases"
const releaseJSONFileName string = "releases.json"
// ReleaseJSON contains information about releases of various MIG components,
// such as the agent, the agent configuration generator tool, and so on.
type ReleaseJSON struct {
Agent Component `json:"agent"`
AgentConfigTool Component `json:"agentConfig"`
Agent Component `json:"agent"`
AgentConfigTool Component `json:"agentConfig"`
}
// Component describes the latest and all past releases of MIG components,
// such as the agent and its configuration generator tool, and past releases.
type Component struct {
LatestReleaseTag string `json:"latest"`
ReleaseHistory []Release `json:"releases"`
LatestReleaseTag string `json:"latest"`
ReleaseHistory []Release `json:"releases"`
}
// Release contains information about a release of any component.
type Release struct {
Tag string `json:"tag"`
Date string `json:"date"`
Notes string `json:"notes"`
Sha256 string `json:"sha256"`
Tag string `json:"tag"`
Binary string `json:"binary"`
Date string `json:"date"`
Notes string `json:"notes"`
Sha256 string `json:"sha256"`
}
// formatDate translates a date into a "year/month/day" format, using
// 1-based indexes for days and months to be human readable.
// For example, August 16, 2018 is formatted "2018/8/16".
func formatDate(date time.Time) string {
year, month, day := date.Date()
return fmt.Sprintf("%d/%d/%d", year, int(month), day)
year, month, day := date.Date()
return fmt.Sprintf("%d/%d/%d", year, int(month), day)
}
// setLatestRelease updates a component with a new release, setting the
// latest release tag and adding to its release history.
func setLatestRelease(comp *Component, tag, notes, sha256 string) {
comp.LatestReleaseTag = tag
func setLatestRelease(comp *Component, binaryName, tag, notes, sha256 string) {
comp.LatestReleaseTag = tag
comp.ReleaseHistory = append(comp.ReleaseHistory, Release{
Tag: tag,
Date: formatDate(time.Now()),
Notes: notes,
Sha256: sha256,
})
comp.ReleaseHistory = append(comp.ReleaseHistory, Release{
Tag: tag,
Binary: binaryName,
Date: formatDate(time.Now()),
Notes: notes,
Sha256: sha256,
})
}
// knownComponents returns a list of names of components understood by this
// tool, for which new releases can be documented.
func knownComponents() []string {
return []string{
"agent",
"agentConfig",
}
return []string{
"agent",
"agentConfig",
}
}
// component retrievses a pointer to a known component identified by its name,
// which must match one of the "knownComponents", so that a new release can be
// appended to it.
func component(releases *ReleaseJSON, compName string) (*Component, error) {
switch compName {
case "agent":
return &releases.Agent, nil
case "agentConfig":
return &releases.AgentConfigTool, nil
default:
return nil, fmt.Errorf("unknown component \"%s\"", compName)
}
switch compName {
case "agent":
return &releases.Agent, nil
case "agentConfig":
return &releases.AgentConfigTool, nil
default:
return nil, fmt.Errorf("unknown component \"%s\"", compName)
}
}
// isUniqueTag determines whether a particular tag already appears in a
// component's release history or not.
func isUniqueTag(comp Component, tag string) bool {
for _, release := range comp.ReleaseHistory {
if release.Tag == tag {
return false
}
}
return true
for _, release := range comp.ReleaseHistory {
if release.Tag == tag {
return false
}
}
return true
}
// usage prints a usage string giving a more detailed explanation about
// how to use this tool.
func usage() {
fmt.Fprintf(os.Stderr, "This program is used to update a JSON file describing releases of MIG components.\n\n")
fmt.Fprintf(os.Stderr, "Note that the -component and -tag arguments are required.\n\n")
flag.PrintDefaults()
fmt.Fprintf(os.Stderr, "This program is used to update a JSON file describing releases of MIG components.\n\n")
fmt.Fprintf(os.Stderr, "Note that the -component, -binary and -tag arguments are required.\n\n")
flag.PrintDefaults()
}
func main() {
flag.Usage = usage
flag.Usage = usage
releaseJSONPath := flag.String(
"releases",
path.Join(defaultReleasesDir, releaseJSONFileName),
fmt.Sprintf("Path to the %s file to update", releaseJSONFileName))
componentName := flag.String(
"component",
"",
fmt.Sprintf(
"The name of the component to update. Must be one of: %s",
strings.Join(knownComponents(), ", ")))
tag := flag.String(
"tag",
"",
"A unique tag string identifying the release")
notes := flag.String(
"notes",
"",
"Notes describing the release")
sha256 := flag.String(
"sha256",
"",
"Hex encoding of the SHA256 hash of the released binary")
releaseJSONPath := flag.String(
"releases",
path.Join(defaultReleasesDir, releaseJSONFileName),
fmt.Sprintf("Path to the %s file to update", releaseJSONFileName))
componentName := flag.String(
"component",
"",
fmt.Sprintf(
"The name of the component to update. Must be one of: %s",
strings.Join(knownComponents(), ", ")))
binary := flag.String(
"binary",
"",
"The name of the binary file")
tag := flag.String(
"tag",
"",
"A unique tag string identifying the release")
notes := flag.String(
"notes",
"",
"Notes describing the release")
sha256 := flag.String(
"sha256",
"",
"Hex encoding of the SHA256 hash of the released binary")
flag.Parse()
flag.Parse()
releaseFile, err := os.Open(*releaseJSONPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not open releases JSON file \"%s\"\n", *releaseJSONPath)
os.Exit(1)
}
defer releaseFile.Close()
releaseFile, err := os.Open(*releaseJSONPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Could not open releases JSON file \"%s\"\n", *releaseJSONPath)
os.Exit(1)
}
defer releaseFile.Close()
var releaseJSON ReleaseJSON
decoder := json.NewDecoder(releaseFile)
decodeErr := decoder.Decode(&releaseJSON)
if decodeErr != nil {
fmt.Fprintf(os.Stderr, "Failed to decode release JSON. Error: %s\n", decodeErr.Error())
os.Exit(1)
}
var releaseJSON ReleaseJSON
decoder := json.NewDecoder(releaseFile)
decodeErr := decoder.Decode(&releaseJSON)
if decodeErr != nil {
fmt.Fprintf(os.Stderr, "Failed to decode release JSON. Error: %s\n", decodeErr.Error())
os.Exit(1)
}
component, err := component(&releaseJSON, *componentName)
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid component specified. Error: %s\n", err.Error())
os.Exit(1)
}
component, err := component(&releaseJSON, *componentName)
if err != nil {
fmt.Fprintf(os.Stderr, "Invalid component specified. Error: %s\n", err.Error())
os.Exit(1)
}
if *tag == "" {
fmt.Fprintf(os.Stderr, "No tag identifier supplied.\n")
os.Exit(1)
}
if *binary == "" {
fmt.Fprintf(os.Stderr, "No binary name supplied.\n")
}
setLatestRelease(component, *tag, *notes, *sha256)
if *tag == "" {
fmt.Fprintf(os.Stderr, "No tag identifier supplied.\n")
os.Exit(1)
}
prefix := ""
indent := " "
encoded, _ := json.MarshalIndent(releaseJSON, prefix, indent)
fmt.Printf("%s\n", string(encoded))
setLatestRelease(component, *binary, *tag, *notes, *sha256)
prefix := ""
indent := " "
encoded, _ := json.MarshalIndent(releaseJSON, prefix, indent)
fmt.Printf("%s\n", string(encoded))
}