Azure DevOpsの別のProjectやOrganizationにいるソースコードの同期をPipelineで自動化する
Azure DevOpsで複数のチームで開発する場合、Forkで別のProjectに共有したりPAT(Personal Access Token)で別のOrganization配下のProject間でソースコードを共有したりすることができます。
※PATを使ってOrganization間でソースコードを共有する方法は過去のこちらの記事をご覧ください(Forkで別のProjectに共有する方法の記事は現在準備中!)
複数のProject間でRepositoryのソースコードをやり取りする場合、効率的なコードの同期と管理が運用の上でキーになります。
今回の記事では複数Project間でソースコードを同期するステップをPipelineで自動化する方法について紹介します。
上流(Upstream)と下流(Downstream)のRepository
ソースを複数のProject間で共有する場合、そのProjectのRepositoryは「上流(Upstream)」と「下流(DownStream)」という関係で表されます。
今回は、Project AlphaをオリジナルのRepository(上流)、Project BravoをAlphaからソースを受け取る下流のRepositoryとして、同期の仕方を説明していきます。
Project AlphaとProject Bravoの関係は以下のようになっています。
- 上流のProject Alphaのmainブランチが更新されたら、下流のProject Bravoのalpha-baseブランチに更新内容を同期する
- 下流のProject Bravoのブランチ戦略は以下のようになっており、mainブランチから派生したalpha-baseをAlphaのソースの同期専用のブランチとしている
main(Bravoでプロダクト開発を行うためのbranch) ←alpha-baseをmerge : これをdefaultとする
└── alpha-base: ここにReomote Reposとして登録したAlphaからプロダクトコードをpullする
※alpha-baseは上流のProject Alphaからのソースコードを取得するのみ。これによりBravoで開発中のプロダクトコードへの汚されと同期の際のconflictを回避する。integrationはmainにmergeする際に行う。
上流Reposと下流Reposの同期のステップ
同期のフローは下記のようになります。
- 上流のProject Alphaのmainブランチが更新される(コードがpushされる)
- 下流のProject Bravoで上流のProject Alphaをupstreamとしてremote repositoryに登録する(※これをするためにProjetc AlphaのソースのRead権限があるPATが必要)
- Project Bravoのalpha-baseブランチで2で登録したremote repositoryから変更を取得する
- alpha-baseのリモートブランチにpushする
2, 3, 4のステップをまじめにGitコマンドで一通り書くとこんな感じになります。
■作業環境:Project Bravo
// 下流のProject Bravoで上流のProject Alphaをupstreamとしてremote repositoryに登録
$ git remote add upstream https://{YOUR_PAT}@dev.azure.com/{YOUR_ORGANIZATION_NAME}/{YOUR_PROJECT_NAME}/_git/{YOUR_REPOS_NAME} {BRANCH_NAME}
// upstream(上流)の更新情報を取得
$ git fetch upstream
// upstreamの変更を取得する専用のalpha-baseブランチに切替
$ git checkout alpha-base
// upstreamtのmainブランチから変更を取得
$ git pull origin upstream main
// alpha-baseのリモートブランチに変更をpush
$ git push origin alpha-base
再掲ですが、この辺のステップの詳細は以下の過去の記事をご覧ください。
手動でまじめにやる場合はこんな感じになりますが、一回やったらめんどくさかったのでPipelineでこれを自動化します。
Project AlphaにBuild Pipelineを作成
前提として、上流のProject Alphaのmainブランチに更新が入った場合にProject Bravoにソースを同期したいので、このイベントを自動化の際のトリガーとしてProject AlphaにPipelineを構成していきます。
1. Project BravoのCodeのRead&WriteができるPATを作成
■作業環境:Project Bravo
Project AlphaのPipelieでProject Bravoのソースを同期したいので、Project AlphaからBravoのRepositoryに対してアクセスできるように、BravoでPATを作成します。
Azure DevOpsで別のProjectやOrganizationに対して何かしたい場合、ターゲットの環境のPATさえあれば大抵のことはなんとかなります。
Project Bravoの右上のUser Settings(人に⚙のアイコンのやつ)を選択 > Personal Aaccess Tokenを選択します。
New Tokenを選択
各項目を設定
- NameでPATの名前を
- OrganizationでこのPATでアクセスできるOrganizationを
- ExpirationでPATのアクセス期限を(最長で1年ぐらい設定可能)
- ScopesでCustom difinedを(Full Accessにするとなんでもできてしまうので、セキュリティ的にリスク高いのでおすすめしません)
-
(ここが大事 CodeでRead&Writeを選択(今回はBravoのRepositoryへの同期が必要なので)
設定が完了後、Createを押下するとPATが作成される。
2. Project AlphaのReposのルートに.ymlファイルを作成
BravoのReposへのRead&writeができるPATができたので、これを使ってProject AlphaでPipelineを作っていきます。
■作業環境:Project Alphaのmainブランチ
Azure DevOpsのPipelineはymlファイルをベースに実行されます。
Azure DevOpsでソースを同期したいRepositoryに移動します。
また、今回のトリガーは 「Alphaのmainブランチにコードがpushされること」 なので、トリガーが発火されるmainブランチでPipelineを作成するので、mainブランチに移動して下さい。
- New > Fileでymlファイルを作成します。
今回はsync-asset-pipeline.yml
という名称にしてます。
ファイル名を入力したらCreatを押下して下さい。
ファイル作成後、Commitを押下
ここでコミットメッセージを設定してcommitを押下し、mainに直にcommitします。
これでPipelineのベースとなるymlファイルが作成されました。
3. ymlファイルをベースにPipelineを作成
Azure DevOpsの左メニューでPipelineを選択
右上のNew pipelineを選択
Pipelineで同期したいコードはAzDOのReposにいるので、Where is your code?ではAzure Repos Gitを選択
Repsositoryの選択。同じく、同期したいコードがいるのはProject AlphaのRepositoryを選択。
何をベースにPipelineを構成するか選択。
今回はすでにProject AlphaのReposのmainブランチにベースになるsync-asset-pipeline.yml
を作成したので、Exsiting Azure Pipelines YAML fileを選択。
Branchがmainであることを確認し(今回はイベントの発火:CodeへのPushを拾うのがmainブランチなのでmainを選択しますが、別のブランチへのpushを拾いたい場合は別のブランチを選択する必要があります)、Pathで先程Pipelineのベースとして作ったsync-asset-pipeline.yml
をドロップダウンから選択(ymlファイルがドロップダウンで選択できるようになっている)。
選択が完了したら、Continueを押下。
ymlファイルの編集画面になるので、以下のように設定。
//コメントはあくまで説明なので実際動かすときは除外して下さい
// mainブランチにpushされたのをトリガーとする
trigger:
branches:
include:
- main
pool:
vmImage: 'windows-latest'
// jobの名前をSnynAlphaと定義している
// 最初のstepでcheckout: selfで自分自身(main)をcheckout
jobs:
- job: SyncAlpha
steps:
- checkout: self
// ここで実行したいbashスクリプトを設定
- script: |
git config user.email "{YOUR_EMAIL}"
git config user.name "{YOUR_USER_NAME}"
// ローカルではremote reposの追加は一度でよいが、Pipelineで動かす場合は毎回の実行ごとに環境が初期化されるのでremote addのstepも必要。
// BravoのPATを使用してProject Bravoをbravo-remoteという名前でremote reposに追加。すでにある場合は"bravo-remote already added"のメッセージを返す。
git remote add bravo-remote https://$(PAT_BRAVO)@dev.azure.com/{YOUR_ORGANIZATION}/Project_Bravo/_git/{Bravoの同期したいReposの名前} || echo "bravo-remote already added"
git fetch bravo-remote alpha-base
// ローカルでalpha-baseというブランチを新規作成して切替
git checkout -b alpha-base
// origin main(Project Alpha)のmainブランチを取得してBravoのalpha-baseブランチにpush
git pull --rebase origin main
git push -f bravo-remote alpha-base
displayName: 'Sync Project Alpha changes to Bravo'
右上のVariablesを押下し、
+(New variables)を選択
- Nameで変数名を設定
- Valueで値(今回の場合は1で作成したBravoのPAT)を設定
※Keep this value secretにするとこの作成するタイミング以降は値がマスクされ、PATの漏洩リスクが低くなりセキュリティが高まります
To reference a variable in YAML, prefix it with a dollar sign and enclose it in parentheses. For example: $(PAT_BRAVO)
と書いてある通り、ymlファイル内でこの変数を使用する際は$(value)の形式で使用してください。
作成したら、Variablesで使用したい変数名の右の赤枠箇所を押下すると、クリップボードに$(value)
の形式でコピーされるので、ymlファイル内で使用したい箇所で使用してください。
以上でPipelineの設定が完了です。
Runを押下すれば、Pipelineを実行できます。
試しにProject AlphaのReadMeをこんな感じで更新すると
Pipelineが動いてProject BravoのReadMeも更新されました。
※Pipelineの実行状況と結果はPipelinesのメニューから確認できます。
References
Discussion