func main()

in cmd/locktrigger/main.go [65:172]


func main() {
	flag.Usage = usage
	flag.Parse()
	log.SetPrefix("locktrigger: ")
	log.SetFlags(0)

	if *project == "" || *build == "" || *repo == "" {
		usage()
	}

	ctx := context.Background()
	c, err := cloudbuild.NewClient(ctx)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	// Find commit hash of local Git
	myHash := run("git", "rev-parse", "HEAD")
	log.Printf("my hash: %v", myHash)

	// Find build object for current build, check that it matches.
	self := getBuild(c, ctx, *build)
	if hash := self.Substitutions["COMMIT_SHA"]; hash != myHash {
		log.Fatalf("build COMMIT_SHA does not match local hash: %v != %v", hash, myHash)
	}
	log.Printf("my build: %v", self.Id)
	if self.BuildTriggerId == "" {
		log.Fatalf("build has no trigger ID")
	}
	log.Printf("my trigger: %v", self.BuildTriggerId)

	// List all builds for our trigger that are still running.
	req := &cloudbuildpb.ListBuildsRequest{
		ProjectId: *project,
		// Note: Really want "status=WORKING buildTriggerId="+self.BuildTriggerId,
		// but that fails with an InvalidArgument error for unknown reasons.
		// status=WORKING will narrow the list down to something reasonable,
		// and we filter the unrelated triggers below.
		Filter: "status=WORKING",
	}
	it := c.ListBuilds(ctx, req)
	foundSelf := false
	shallow := false
	if _, err := os.Stat(run("git", "rev-parse", "--git-dir") + "/shallow"); err == nil {
		shallow = true
	}
	for {
		b, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatalf("reading builds: %v (%q)", err, req.Filter)
		}
		if b.BuildTriggerId != self.BuildTriggerId {
			continue
		}

		// Check whether this build is an older or newer commit.
		// If this build is older, cancel it.
		// If this build is newer, cancel ourselves.
		if b.Id == self.Id {
			foundSelf = true
			continue
		}
		hash := b.Substitutions["COMMIT_SHA"]
		if hash == "" {
			log.Fatalf("cannot find COMMIT_SHA for build %v", b.Id)
		}
		if hash == myHash {
			log.Fatalf("found another build %v at same commit %v", b.Id, hash)
		}

		// Fetch the full Git repo so we can answer the history questions.
		// This is delayed until now to avoid the expense of fetching the full repo
		// if we are the only build that is running.
		if shallow {
			log.Printf("git fetch --unshallow")
			run("git", "fetch", "--unshallow", *repo)
			shallow = false
		}

		// Contention.
		// Find the common ancestor between us and that build,
		// to tell whether we're older, it's older, or we're unrelated.
		log.Printf("checking %v", hash)
		switch run("git", "merge-base", myHash, hash) {
		default:
			log.Fatalf("unexpected build for unrelated commit %v", hash)

		case myHash:
			// myHash is older than b's hash. Cancel self.
			log.Printf("canceling self, for build %v commit %v", b.Id, hash)
			cancel(c, ctx, self.Id)

		case hash:
			// b's hash is older than myHash. Cancel b.
			log.Printf("canceling build %v commit %v", b.Id, hash)
			cancel(c, ctx, b.Id)
		}
	}

	// If we listed all the in-progress builds, we should have seen ourselves.
	if !foundSelf {
		log.Fatalf("reading builds: didn't find self")
	}
}