Skip to content

Instantly share code, notes, and snippets.

@rail
Created January 10, 2022 17:23
Show Gist options
  • Save rail/8f7fcf8d98be2b28d94f89db4aadd731 to your computer and use it in GitHub Desktop.
Save rail/8f7fcf8d98be2b28d94f89db4aadd731 to your computer and use it in GitHub Desktop.
build/release/teamcity-mark-build-qualified.sh | 3 +-
build/release/teamcity-mark-build.sh | 30 +++++++
pkg/cmd/release/BUILD.bazel | 15 ++++
pkg/cmd/release/main.go | 109 +++++++++++++++++++++++++
4 files changed, 156 insertions(+), 1 deletion(-)
diff --git a/build/release/teamcity-mark-build-qualified.sh b/build/release/teamcity-mark-build-qualified.sh
index ca9f00cbbf..145b2bb2f4 100755
--- a/build/release/teamcity-mark-build-qualified.sh
+++ b/build/release/teamcity-mark-build-qualified.sh
@@ -1,7 +1,8 @@
#!/usr/bin/env bash
set -euxo pipefail
source "$(dirname "${0}")/teamcity-mark-build.sh"
-mark_build "qualified"
+# TODO: temp //// mark_build "qualified"
+publish_metadata
diff --git a/build/release/teamcity-mark-build.sh b/build/release/teamcity-mark-build.sh
index 25acb1da85..8970bae0a3 100755
--- a/build/release/teamcity-mark-build.sh
+++ b/build/release/teamcity-mark-build.sh
@@ -26,8 +26,38 @@ mark_build() {
echo "This tag/branch does not contain a valid major version. Tag/Branch=\"${TC_BUILD_BRANCH}\". Unable to tag docker image as qualified."
exit
fi
log_into_gcloud
gcloud container images add-tag "${gcr_repository}:${TC_BUILD_BRANCH}" "${gcr_repository}:latest-${release_branch}-${build_label}-build"
tc_end_block "Push new docker image tag"
}
+
+publish_metadata() {
+ # TODO: move to a separate file
+ tc_start_block "Metadata"
+ # ignore master builds
+ ##### echo $TC_BUILD_BRANCH | grep -q alpha && return
+ # release-21.2
+ release_branch=$(echo $TC_BUILD_BRANCH | awk -F- '{print $1}' | sed 's/^v//' | awk -F. '{print "release-" $1 "." $2}')
+ # The tag contains a version number which has to be bumped by 1
+ release_version=$(echo $TC_BUILD_BRANCH | awk -F- '{print $1}' | awk -F. '{print $1 "." $2 "." $3+1}')
+ # TODO: create a GCS bucket
+ # TODO: create credentials to publish to the bucket above
+ timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
+ mkdir -p artifacts
+ metadata_file="artifacts/$release_version.json"
+ cat > "$metadata_file" << EOF
+{
+ "version": "$release_version",
+ "branch": "$release_branch",
+ "sha": "$BUILD_VCS_NUMBER",
+ "timestamp": "$timestamp",
+ "tag": "$TC_BUILD_BRANCH"
+}
+EOF
+ # verify json
+ cat "$metadata_file"
+ # TODO: set the bucket, dry run bucket
+ ### gsutil cp "$release_version.json" "gs://$gcs_bucket/releases/$release_version.json"
+ tc_end_block "Metadata"
+}
diff --git a/pkg/cmd/release/BUILD.bazel b/pkg/cmd/release/BUILD.bazel
new file mode 100644
index 0000000000..ce9d8171a1
--- /dev/null
+++ b/pkg/cmd/release/BUILD.bazel
@@ -0,0 +1,15 @@
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+go_library(
+ name = "release_lib",
+ srcs = ["main.go"],
+ importpath = "github.com/cockroachdb/cockroach/pkg/cmd/release",
+ visibility = ["//visibility:private"],
+ deps = ["@com_github_spf13_cobra//:cobra"],
+)
+
+go_binary(
+ name = "release",
+ embed = [":release_lib"],
+ visibility = ["//visibility:public"],
+)
diff --git a/pkg/cmd/release/main.go b/pkg/cmd/release/main.go
new file mode 100644
index 0000000000..437799e8e1
--- /dev/null
+++ b/pkg/cmd/release/main.go
@@ -0,0 +1,109 @@
+package main
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+
+ "cloud.google.com/go/storage"
+ "github.com/spf13/cobra"
+)
+
+type metadata struct {
+ Version string `json:"version"`
+ Tag string `json:"tag"`
+ Branch string `json:"branch"`
+ SHA string `json:"sha"`
+ Timestamp string `json:"timestamp"`
+}
+
+func (m metadata) marshall() ([]byte, error) {
+ ret, err := json.MarshalIndent(m, "", " ")
+ if err != nil {
+ return nil, err
+ }
+ return ret, nil
+}
+
+func main() {
+ cmdPickSHA := &cobra.Command{
+ Use: "pick-sha qualify-url publish-url",
+ Short: "Pick release git sha for a particular version and communicate the decision",
+ Long: `Pick release sha, send email, create Jira ticket, etc.`,
+ Args: cobra.ExactArgs(2),
+ RunE: pickSHA,
+ }
+ cmdPickSHA.Flags().String("email", "", "email of list")
+ cmdPickSHA.Flags().String("fetch-bucket", "", "fetch bucket")
+ cmdPickSHA.Flags().String("fetch-object", "", "fetch object")
+ cmdPickSHA.Flags().String("publish-bucket", "", "publish bucket")
+ cmdPickSHA.Flags().String("publish-object", "", "publish object")
+ rootCmd := &cobra.Command{Use: "release"}
+ rootCmd.AddCommand(cmdPickSHA)
+ err := rootCmd.Execute()
+ if err != nil {
+ panic(err)
+ }
+}
+
+func pickSHA(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ meta, err := fetchVersionJSON(ctx, cmd.Flags().GetString("fetch-bucket"), cmd.Flags().GetString("fetch-object"))
+ // TODO: copy the metadata to a stable location where it's not overwritten by qualify build
+ // TODO: before copying check if it's already there and bail if exists, can be forced by -f
+ if err != nil {
+ return err
+ }
+ if err := publishJSON(ctx, meta); err != nil {
+ // TODO: combine errors
+ // TODO: add flag to skip this step
+ return err
+ }
+ if err := postToJira(ctx, meta); err != nil {
+ // TODO: combine errors
+ // TODO: add flag to skip this step
+ return err
+ }
+ if err := sendEmail(ctx, meta); err != nil {
+ // TODO: combine errors
+ // TODO: add flag to skip this step
+ return err
+ }
+ return nil
+}
+func fetchVersionJSON(ctx context.Context, bucket string, obj string) (metadata, error) {
+ // TODO: add retry
+ fmt.Println("version", bucket, obj)
+ return metadata{}, nil
+}
+
+func publishJSON(ctx context.Context, meta metadata) error {
+ out, err := meta.marshall()
+ if err != nil {
+ return fmt.Errorf("cannot marshall metadata: %w", err)
+ }
+ client, err := storage.NewClient(ctx)
+ // TODO: pass bucket and object
+ bucket := "bucket"
+ obj := "obj.json"
+ if err != nil {
+ return fmt.Errorf("cannot create storage client: %w", err)
+ }
+ wc := client.Bucket(bucket).Object(obj).NewWriter(ctx)
+ wc.ContentType = "application/json"
+ if _, err := wc.Write(out); err != nil {
+ return fmt.Errorf("cannot write to bucket: %w", err)
+ }
+ if err := wc.Close(); err != nil {
+ return fmt.Errorf("cannot close storage writer filehandle: %w", err)
+ }
+ return nil
+}
+
+func sendEmail(ctx context.Context, meta metadata) error {
+ return nil
+}
+
+func postToJira(ctx context.Context, meta metadata) error {
+ return nil
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment