Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 16897] ファイルの概要

このコミットは、Go言語のビルドダッシュボード(misc/dashboard)における挙動の変更に関するものです。具体的には、リリースブランチからのコミットに対して、tipタグの更新を行わないように修正しています。これにより、サブモジュール(サブリポジトリ)がリリースブランチのコードと互換性がない場合に、不必要なビルドやテストの失敗を防ぐことを目的としています。

コミット

commit e87af8c43d5801c20e698aeb8c96577c4e881755
Author: David Symonds <dsymonds@golang.org>
Date:   Mon Jul 29 12:08:19 2013 +1000

    misc/dashboard: don't update tip tag for release branch commits.
    
    This will mean that sub-repositories won't get built against the
    release branch. They are often not compatible because the subrepos
    often run ahead of the current release (e.g. go.tools is using
    new additions to go/ast, and go.net is using new things in syscall)
    so there's little point in checking them against cherrypick commits
    when they'll be tested against those commits on tip anyway.
    
    R=golang-dev, adg
    CC=golang-dev
    https://golang.org/cl/12001043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/e87af8c43d5801c20e698aeb8c96577c4e881755

元コミット内容

misc/dashboard: don't update tip tag for release branch commits.

このコミットは、リリースブランチからのコミットに対して、tipタグの更新を行わないようにします。

これは、サブリポジトリがリリースブランチに対してビルドされないことを意味します。サブリポジトリは、現在のリリースよりも先行していることが多いため(例:go.toolsgo/astの新しい追加機能を使用している、go.netsyscallの新しい機能を使用しているなど)、互換性がないことがよくあります。そのため、チェリーピックされたコミットに対してそれらをチェックしても意味がほとんどなく、いずれにせよtip(開発版の最新)に対してテストされることになります。

変更の背景

Go言語の開発プロセスでは、メインのGoリポジトリ(golang/go)と、go.toolsgo.netといった独立したサブリポジトリが存在します。これらのサブリポジリは、メインリポジトリの特定のパッケージに依存しており、メインリポジトリの進化に合わせて更新されます。

問題は、Goのリリースブランチ(例: release-branch.go1.1)にチェリーピックされるコミット(バグ修正など)が、必ずしもサブリポジトリの最新の状態と互換性があるとは限らない点にありました。サブリポジトリは、メインリポジトリのmaster(またはtip)ブランチの最新の変更に合わせて開発が進められることが多く、リリースブランチの古いAPIや構造では動作しない可能性があります。

Goのビルドダッシュボードは、様々なコミットに対してGo本体とサブリポジトリのビルドとテストを実行し、その健全性を監視しています。以前の挙動では、リリースブランチへのコミットがあった際にも、メインリポジトリの最新開発版を示すtipタグが更新されていました。これにより、サブリポジトリがリリースブランチのコードベースに対してビルド・テストされることになり、互換性のない変更のために不必要なビルド失敗やテストエラーが発生していました。

このコミットの背景には、このような無駄なビルドとテストのサイクルを避け、ダッシュボードの効率性を向上させるという目的があります。サブリポジトリは最終的にtipブランチに対してテストされるため、リリースブランチのコミットでtipタグを更新する必要はないという判断がなされました。

前提知識の解説

このコミットを理解するためには、以下のGo言語の開発・ビルドエコシステムに関する知識が必要です。

  1. Go言語のバージョン管理とリリースブランチ:

    • Go言語はセマンティックバージョニング(MAJOR.MINOR.PATCH)に準拠したリリースサイクルを持っています。
    • 新しいメジャーバージョン(例: Go 1.x)がリリースされると、そのバージョンに対応するリリースブランチ(例: release-branch.go1.1)が作成されます。
    • このリリースブランチは、そのバージョンの安定版として維持され、主にバグ修正やセキュリティパッチがチェリーピック(他のブランチから特定のコミットを選択して取り込むこと)されます。
    • 一方、**masterブランチ(またはtip)**は、次のメジャーリリースに向けた活発な開発が行われる場所です。最新の機能追加やAPI変更はここで行われます。
  2. Goのサブリポジトリ (Sub-repositories):

    • Goプロジェクトは、メインのgolang/goリポジトリだけでなく、golang.org/x/以下に多数の独立したサブリポジトリを持っています。
    • 例: go.tools (Goツール群、例: go vet, go docなど), go.net (ネットワーク関連パッケージ), go.text (テキスト処理パッケージ) など。
    • これらのサブリポジリは、メインのGoリポジトリの特定のパッケージ(例: go/ast, syscall)に依存しています。
    • サブリポジトリの開発は、メインリポジトリのmasterブランチの最新の変更に合わせて進められることが一般的です。つまり、サブリポジトリはメインリポジトリのmasterブランチの「先行」バージョンに依存していることが多いです。
  3. Goのビルドダッシュボード (misc/dashboard):

    • misc/dashboardは、Goプロジェクトの継続的インテグレーション(CI)システムの一部です。
    • 世界中の様々な環境(OS、アーキテクチャ、コンパイラなど)で、Go本体とサブリポジトリのビルドとテストを自動的に実行し、その結果をウェブインターフェースで表示します。
    • これにより、Go本体やサブリポジトリへの変更が、様々な環境で問題なく動作するかどうかを継続的に監視し、品質を保証しています。
    • ダッシュボードは、特定のコミットハッシュや「タグ」(例: tip)に基づいてビルドとテストを実行します。
  4. tipタグ:

    • Goのビルドダッシュボードにおいて、「tip」タグは、Goメインリポジトリのmasterブランチにおける最新のコミットハッシュを指します。
    • これは、Goの最新の開発版を表すものであり、サブリポジトリのビルドやテストは通常、このtipに対して行われます。

技術的詳細

このコミットの技術的な核心は、Goビルドダッシュボードのバックエンドロジックにおけるtipタグの更新条件の変更にあります。

Goのビルドダッシュボードは、新しいコミットがGoリポジトリにプッシュされるたびに、そのコミット情報を処理します。この処理の一部として、メインのGoリポジトリ(p.Path == ""で識別される)に対するコミットの場合、そのコミットハッシュをtipタグとしてデータストアに保存するロジックがありました。

しかし、Goのリリースブランチ(例: release-branch.go1.1)へのコミットは、通常、masterブランチからチェリーピックされたバグ修正などです。これらのコミットは、masterブランチの最新の状態とは異なる、より古いAPIや構造を持つ可能性があります。

一方で、go.toolsgo.netのようなサブリポジトリは、メインのGoリポジトリのmasterブランチの最新の変更(つまりtip)に合わせて開発が進められています。これは、サブリポジトリがgo/astsyscallといったメインリポジトリのパッケージの新しい機能や変更に依存しているためです。

したがって、リリースブランチへのコミットがあった際にtipタグを更新してしまうと、ダッシュボードはサブリポジトリを、それらが依存しているメインリポジトリのパッケージの「古い」バージョン(リリースブランチのバージョン)に対してビルド・テストしようとします。これにより、サブリポジトリのコードがリリースブランチのAPIと互換性がなく、ビルドエラーやテスト失敗が頻繁に発生していました。これらの失敗は、サブリポジトリがtipに対しては正しく動作するため、誤ったアラートとなり、ダッシュボードの監視効率を低下させていました。

このコミットは、この問題を解決するために、tipタグの更新条件に「コミットがリリースブランチからのものでないこと」という条件を追加しました。具体的には、コミットメッセージの先頭が[release-branchで始まるかどうかをチェックすることで、リリースブランチからのコミットを識別しています。これにより、リリースブランチへのコミットがあってもtipタグは更新されず、サブリポジトリは常にメインリポジトリのmasterブランチの最新の状態(真のtip)に対してビルド・テストされるようになります。

コアとなるコードの変更箇所

変更はmisc/dashboard/app/build/handler.goファイルにあります。

--- a/misc/dashboard/app/build/handler.go
+++ b/misc/dashboard/app/build/handler.go
@@ -11,6 +11,7 @@ import (
 	"errors"
 	"fmt"
 	"net/http"
+	"strings"
 
 	"appengine"
 	"appengine/datastore"
@@ -98,8 +99,8 @@ func addCommit(c appengine.Context, com *Commit) error {
 			return errors.New("parent commit not found")
 		}
 	}
-	// update the tip Tag if this is the Go repo
-	if p.Path == "" {
+	// update the tip Tag if this is the Go repo and this isn't on a release branch
+	if p.Path == "" && !strings.HasPrefix(com.Desc, "[release-branch") {
 		t := &Tag{Kind: "tip", Hash: com.Hash}
 		if _, err = datastore.Put(c, t.Key(c), t); err != nil {
 			return fmt.Errorf("putting Tag: %v", err)

コアとなるコードの解説

このコミットの主要な変更は、addCommit関数内のif文の条件式にあります。

  1. import "strings" の追加:

    • コミットメッセージのプレフィックスをチェックするために、Go標準ライブラリのstringsパッケージがインポートされました。このパッケージは文字列操作のためのユーティリティ関数を提供します。
  2. if 文の条件変更:

    • 変更前: if p.Path == "" {
      • この条件は、処理中のコミットがメインのGoリポジトリ(サブリポジトリではない)からのものであることをチェックしていました。p.Pathが空文字列の場合、それはメインのGoリポジトリからのコミットを意味します。この条件が真であれば、tipタグが更新されていました。
    • 変更後: if p.Path == "" && !strings.HasPrefix(com.Desc, "[release-branch") {
      • 新しい条件は、元の条件に加えて、&& !strings.HasPrefix(com.Desc, "[release-branch") という部分が追加されています。
      • com.Descはコミットのディスクリプション(コミットメッセージの本文)を表します。
      • strings.HasPrefix(com.Desc, "[release-branch") は、コミットメッセージの本文が文字列 "[release-branch" で始まるかどうかをチェックします。Goのリリースブランチへのチェリーピックコミットは、慣例としてコミットメッセージの先頭に [release-branch.go1.x] のようなプレフィックスを持つことが多いため、このチェックでリリースブランチからのコミットを識別できます。
      • ! 演算子により、この条件全体は「コミットメッセージが [release-branch で始まらない」場合に真となります。

この変更により、tipタグが更新されるのは、以下の両方の条件が満たされる場合のみとなります。

  1. コミットがメインのGoリポジトリからのものである (p.Path == "")。
  2. コミットがリリースブランチからのものではない (!strings.HasPrefix(com.Desc, "[release-branch"))。

これにより、リリースブランチへのコミットがあったとしても、tipタグが不適切に更新されることがなくなり、サブリポジトリのビルドとテストが常に最新の開発版(masterブランチ)に対して行われることが保証されます。

関連リンク

参考にした情報源リンク