Pythonプロジェクトのセットアップ:パートV

Pythonプロジェクトのセットアップ:Part V

Pythonプロジェクトセットアップのマスタリング:ステップバイステップガイド

Zoya Loonohodによる写真、Unsplashから

経験豊富な開発者でも、🐍 Python の初心者でも、堅牢で保守可能なプロジェクトの構築方法を知っておくことは重要です。このチュートリアルでは、業界で最も人気のある効果的なツールを使用してPythonプロジェクトのセットアップのプロセスを案内します。バージョン管理と継続的インテグレーションのためにGitHubとGitHub Actionsの使用方法、テスト、ドキュメンテーション、パッケージング、配布のための他のツールについて学びます。このチュートリアルは、Hypermodern PythonやBest Practices for a new Python projectなどのリソースに触発されています。ただし、これは唯一の方法ではなく、異なる好みや意見があるかもしれません。このチュートリアルは初心者向けですが、一部の高度なトピックもカバーしています。各セクションでは、いくつかのタスクを自動化し、プロジェクトにバッジを追加して進捗と成果を表示します。

このシリーズのリポジトリは、github.com/johschmidt42/python-project-johannesで見つけることができます。

この部分は、次のブログ投稿に触発されました:

Python、Poetry&GitHub Actionsでのセマンティックリリース🚀私は同僚からの関心を受けて、Dr. Svenにいくつかの機能を追加する予定です。それを行う前に、必要がありました…

要件

  • OS : Linux、Unix、macOS、Windows(Ubuntu 20.04 LTSなどのWSL2を使用)
  • ツール : python3.10、bash、git、tree
  • バージョン管理システム(VCS)ホスト : GitHub
  • 継続的インテグレーション(CI)ツール : GitHub Actions

バージョン管理システム(VCS)gitに精通していることが期待されています。そうでない場合は、Gitの紹介をご覧ください。

コミットは、gitコミットとConventional commitsのベストプラクティスに基づいて行われます。この形式でコミットを記述するためのPyCharmのconventional commitプラグインやVSCodeの拡張機能があります。

概要

  • パートI(GitHub、IDE)
  • パートII(フォーマット、リンティング、CI)
  • パートIII(テスト、CI)
  • パートIV(ドキュメンテーション、CI/CD)
  • パートV(バージョニング&リリース、CI/CD)
  • パートVI(コンテナ化、Docker、CI/CD)

構造

  • Git ブランチ戦略(GitHubフロー)
  • リリースとは何か(zip、tar.gz)
  • セマンティックバージョニング(v0.1.0)
  • 手動でリリースを作成する(git tag、GitHub)
  • 自動的にリリースを作成する(Conventional commits、セマンティックリリース)
  • CI/CD(release.yml)
  • パーソナルアクセストークン(PAT)の作成
  • GitHub Actionsフロー(ワークフローの組み立て)
  • バッジ(リリース)
  • ボーナス(Conventional commitsの強制)

ソフトウェアのリリースは、新しい機能やバグ修正をユーザーに利用可能にするための重要なステップです。ソフトウェアのリリースの重要な側面の1つは、バージョン管理であり、各リリースで行われた変更を追跡し、伝えるのに役立ちます。セマンティックバージョニングは、ソフトウェアのバージョン管理に広く使用されている標準であり、リリースの変更レベルを示すためにMajor.Minor.Patch(例:1.2.3)の形式のバージョン番号を使用します。

Conventional commitsは、コミットメッセージに人間と機械が読める意味を追加するための仕様です。これは、コミットメッセージを一貫した方法でフォーマットする方法であり、変更のタイプを簡単に特定することができます。コミットメッセージは、リリースのバージョン番号を自動的に決定するために使用されることがあり、セマンティックバージョニングと共により明確で一貫した方法でソフトウェアプロジェクトの各リリースで行われた変更を追跡し、伝えるための方法を提供します。

Git ブランチ戦略

Git にはさまざまなブランチ戦略があります。多くの人々が GitFlow(またはその派生)や Three Flow、Trunk based Flows に傾倒しています。これらの間で戦略を取る人もいて、このようなものもあります。私は非常にシンプルな GitHub フローのブランチ戦略を使用しています。ここではすべてのバグ修正と機能が独自のブランチを持ち、完了後、各ブランチが main にマージされ、展開されます。シンプルで簡単ですね。

GitHub フローのブランチ戦略

どんな戦略を採用しても、最終的にはプルリクエストをマージし、(おそらく)リリースを作成します。

リリースとは何ですか?

簡単に言えば、リリースとはバージョンのコード(たとえば zip)をパッケージ化し、(あなたにとって)本番環境にプッシュすることです。

リリース管理は混乱する場合があります。したがって、リリースが何を意味し、次のリリースとの変更点を定義する(および他の人々も従う)簡潔な方法が必要です。リリース間の変更点を追跡しない場合、各リリースで何が変更されたのか理解できない可能性があり、新しいコードで発生した問題を特定できません。変更履歴がないと、ソフトウェアが時間の経過とともにどのように進化しているかを理解するのは難しくなります。また、必要に応じて変更を元に戻すことも困難になります。

セマンティックバージョニング

セマンティックバージョニングは、ソフトウェア開発業界での数値スキーマと標準的な慣行です。これは、このバージョンと前のバージョンの変更のレベルを示します。セマンティックバージョン番号には、1.8.42 のように3つのパートがあります。

  • メジャーバージョン.マイナーバージョン.パッチバージョン

それぞれが異なる変更の程度を意味します。パッチリリースはバグ修正や些細な変更を示します(たとえば、1.0.0 から 1.0.1 へ)。マイナーリリースは機能の追加/削除や互換性のある変更を示します(たとえば、1.0.0 から 1.1.0 へ)。メジャーリリースは機能の追加/削除および、破壊的な変更などの互換性のない変更を示します(たとえば、1.0.0 から 2.0.0 へ)。

セマンティックバージョニングのリリースについてのビジュアルな紹介をご希望の場合、Mike Miles のトークがおすすめです。これはリリースの概要と、Git タグを使用したセマンティックバージョニングによってリリースを作成できる方法についてまとめたものです。

git タグについて: Git には軽量タグと注釈タグがあります。軽量タグは特定のコミットへのポインターであり、注釈タグは Git の完全なオブジェクトです。

手動でリリースを作成する

まず手動でリリースを作成し、それから自動化します。

覚えているかもしれませんが、example_app の __init__.py ファイルにはバージョンが含まれています

# src/example_app/__init__.py__version__ = "0.1.0"

および pyproject.toml ファイルにも

# pyproject.toml[tool.poetry]name = "example_app"version = "0.1.0"...

したがって、最初に注釈付きの git タグ v0.1.0 を作成し、最新のコミットに追加する必要があります:

> git tag -a v0.1.0 -m "version v0.1.0"

このコマンドの最後にコミットハッシュが指定されていない場合、git は現在のコミットを使用します。

タグのリストを取得するには、次のコマンドを使用します:

> git tagv0.1.0

また、削除する場合は次のコマンドを使用します:

> git tag -d v0.1.0Deleted tag 'v0.1.0'

さらにタグに関する詳細情報を取得するには次のコマンドを使用します:

> git show v0.1.0tag v0.1.0Tagger: Johannes Schmidt <[email protected]>Date:   Sat Jan 7 12:55:15 2023 +0100version v0.1.0commit efc9a445cd42ce2f7ddfbe75ffaed1a5bc8e0f11 (HEAD -> main, tag: v0.1.0, origin/main, origin/HEAD)Author: Johannes Schmidt <[email protected]>Date:   Mon Jan 2 11:20:25 2023 +0100...

新しく作成したタグをoriginにプッシュすることができます。

> git push origin v0.1.0オブジェクトの列挙: 1, 完了.オブジェクトのカウント: 100% (1/1), 完了.オブジェクトの書き込み: 100% (1/1), 171 バイト | 171.00 KiB/s, 完了.合計 1 (デルタ 0), 再利用 0 (デルタ 0), パック再利用 0github.com:johschmidt42/python-project-johannes.git * [new tag]         v0.1.0 -> v0.1.0

これにより、このgitタグがGitHub上で利用可能になります:

このgitタグを使用して、GitHubで新しいリリースを手動で作成します:

Create a new releaseをクリックし、既存のタグ(すでにコミットにバインドされている)を選択し、Generate release notesボタンをクリックしてリリースノートを自動生成し、最後にPublish releaseボタンでリリースを公開します。

GitHubはソースコード用にtarzip(アセット)を自動的に作成しますが、アプリケーションはビルドされません!結果は次のようになります:

まとめると、リリースの手順は次のとおりです:

  • デフォルトのブランチ(たとえば、機能ブランチまたは修正ブランチ)から新しいブランチを作成する
  • 変更を加え、バージョンを増やす(pyproject.tomlと__init__.pyなど)
  • 機能/バグ修正をデフォルトのブランチにコミットする(おそらくプルリクエストを通じて)
  • コミットに注釈付きのgitタグ(セマンティックバージョン)を追加する
  • GitHubでリリースを公開し、追加情報を入力する

自動的にリリースを作成する

プログラマーとして、同じ作業を繰り返すことは好きではありません。そのため、これらの手順を非常に簡単に行うための多くのツールがあります。ここでは、Pythonプロジェクト向けに特に設計されたSemantic Releasesというツールを紹介します。

これは、リポジトリ内にバージョン番号を自動的に設定し、コードにバージョン番号をタグ付けし、リリースを作成するツールです。そして、これはすべてConventional Commitスタイルのメッセージの内容を使用して行われます。

Conventional Commits

セマンティックバージョニングとconventional-commitsの関係は何ですか?

特定のコミットタイプは、セマンティックバージョンのアップを自動的に決定するために使用できます!

  • 修正コミットはPATCHです。
  • 機能コミットはMINORです。
  • BREAKING CHANGEまたは!を含むコミットはMAJORです。

その他のタイプ(buildchorecidocsstylerefactorperftest)は通常、バージョンを増やしません。

プロジェクトで慣例的なコミットを強制する方法については、最後のボーナスセクションを参照してください!

自動的なセマンティックリリース(ローカルで)

次のコマンドでライブラリを追加できます:

> poetry add --group semver python-semantic-release

変更履歴とリリースを自動的に生成するための設定を行いましょう。 pyproject.tomlにsemantic_releaseをツールとして追加できます:

# pyproject.toml...[tool.semantic_release]branch = "main"version_variable = "src/example_app/__init__.py:__version__"version_toml = "pyproject.toml:tool.poetry.version"version_source = "tag"commit_version_number = true # required for version_source = "tag"tag_commit = trueupload_to_pypi = falseupload_to_release = falsehvcs = "github" # gitlab is also supported
  • branch : リリースの基となるブランチを指定します。この場合、「main」ブランチです。
  • version_variable : ソースコード内のバージョン番号のファイルパスと変数名を指定します。この場合、バージョン番号はsrc/example_app/__init__.pyファイルの__version__変数に格納されています。
  • version_toml : pyproject.tomlファイル内のバージョン番号のファイルパスと変数名を指定します。この場合、バージョン番号はpyproject.tomlファイルのtool.poetry.version変数に格納されています。
  • version_source : バージョン番号のソースを指定します。この場合、バージョン番号はタグから取得されます(コミットではなく)。
  • commit_version_number : version_source = "tag"の場合に必要なパラメータです。バージョン番号をリポジトリにコミットするかどうかを指定します。この場合、trueに設定されているため、バージョン番号がコミットされます。
  • tag_commit : リリースコミットのために新しいタグを作成するかどうかを指定します。この場合、trueに設定されているため、新しいタグが作成されます。
  • upload_to_pypi : パッケージをPyPIパッケージリポジトリにアップロードするかどうかを指定します。この場合、falseに設定されているため、パッケージはPyPIにアップロードされません。
  • upload_to_release : パッケージをGitHubのリリースページにアップロードするかどうかを指定します。この場合、falseに設定されているため、パッケージはGitHubのリリースにアップロードされません。
  • hvcs : プロジェクトのホスティングバージョン管理システムを指定します。この場合、”github”に設定されており、プロジェクトはGitHubでホストされています。”gitlab”もサポートされています。

プロジェクト/モジュールのバージョンが定義されているファイルを更新することができます。通常のファイルにはversion_variableを使用し、.tomlファイルにはversion_tomlを使用します。version_sourceはバージョンの真実のソースを定義します。これらの2つのファイルのバージョンは、gitの注釈付きタグと密接に結び付いています。たとえば、リリースごとにgitタグが自動的に作成される(フラグtag_commitがtrueに設定されている)場合、ソースのデフォルト値commitではなくtagを使用することができます。これにより、コミットメッセージの最後のバージョンを探すことができます。ファイルを更新して変更をコミットするためには、commit_version_numberフラグをtrueに設定する必要があります。PythonインデックスPyPiには何もアップロードしたくないため、フラグupload_to_pypiはfalseに設定されています。そして、現時点ではリリースには何もアップロードしたくありません。 hvcsgithub(デフォルト)に設定されており、他の値はgitlabです。

これをローカルでテストするために、いくつかのコマンドを実行することができます。それらを直接Makefileに追加します。

# Makefile...##@ リリースcurrent-version: ## 現在のバージョンを返す @semantic-release print-version --currentnext-version: ## 次のバージョンを返す @semantic-release print-version --nextcurrent-changelog: ## 現在の変更ログを返す @semantic-release changelog --releasednext-changelog: ## 次の変更ログを返す @semantic-release changelog --unreleasedpublish-noop: ## パブリッシュコマンド(ノーオペレーションモード) @semantic-release publish --noop

コマンドcurrent-versionを使用すると、gitツリー内の最後のgitタグからバージョンを取得できます。

> make current-version0.1.0

「feat: new cool feature」や「fix: nasty bug」といった慣例的なコミットスタイルのコミットをいくつか追加した場合、コマンドnext-versionはそのためのバージョンの増加を計算します。

> make next-version0.2.0

現在、プロジェクトにCHANGELOGファイルがないため、次のコマンドを実行すると:

> make current-changelog

出力は空になります。しかし、コミットに基づいて次の変更履歴を作成することができます:

> make next-changelog### Feature* リリースを追加 ([#8](https://github.com/johschmidt42/python-project-johannes/issues/8)) ([`5343f46`](https://github.com/johschmidt42/python-project-johannes/commit/5343f46d9879cc8af273a315698dd307a4bafb4d))* Docstrings ([#5](https://github.com/johschmidt42/python-project-johannes/issues/5)) ([`fb2fa04`](https://github.com/johschmidt42/python-project-johannes/commit/fb2fa0446d1614052c133824150354d1f05a52e9))* app.pyにアプリケーションを追加 ([`3f07683`](https://github.com/johschmidt42/python-project-johannes/commit/3f07683e787b708c31235c9c5357fb45b4b9f02d))### Documentation* 検索バーとgithubのURLを追加 ([#6](https://github.com/johschmidt42/python-project-johannes/issues/6)) ([`3df7c48`](https://github.com/johschmidt42/python-project-johannes/commit/3df7c483eca91f2954e80321a7034ae3edb2074b))* README.pyにページ.ymlのバッジを追加 ([`b76651c`](https://github.com/johschmidt42/python-project-johannes/commit/b76651c5ecb5ab2571bca1663ffc338febd55b25))* Makefileにドキュメンテーションを追加 ([#3](https://github.com/johschmidt42/python-project-johannes/issues/3)) ([`2294ee1`](https://github.com/johschmidt42/python-project-johannes/commit/2294ee105b238410bcfd7b9530e065e5e0381d7a))

新しいコミットをプッシュすると(mainに直接プッシュするか、PRを介してプッシュすると)、次のコマンドで新しいリリースを公開することができます:

> semantic-release publish

公開コマンドは以下の手順を実行します:

  1. 変更履歴ファイルを更新または作成します。
  2. semantic-releaseのバージョンを実行します。
  3. 変更をgitにプッシュします。
  4. build_commandを実行し、配布ファイルをリポジトリにアップロードします。
  5. semantic-release changelogを実行し、vcsプロバイダに投稿します。
  6. build_commandによって作成されたファイルをGitHubリリースに添付します。

もちろん、各ステップは設定や無効化することができます!

CI/CD

GitHub Actionsを使用して、メインブランチへの各コミットでsemantic-releaseの公開コマンドを実行するCIパイプラインを構築しましょう。

lint.yml、test.yml、またはpages.ymlと同じく、全体の構造は同じですが、いくつかの変更があります。ステップのリポジトリのチェックアウトでは、ブランチをチェックアウトするために使用される新しいトークンを追加します。デフォルトの値であるGITHUB_TOKENには、保護されたブランチで操作するために必要な権限がありません。そのため、権限を持つPersonal Access Token(GH_TOKEN)を含むシークレットを使用する必要があります。Personal Access Tokenの生成方法については、後ほど説明します。また、fetch-depth: 0を定義して、すべてのブランチとタグのすべての履歴を取得します。

with:  ref: ${{ github.head_ref }}  token: ${{ secrets.GH_TOKEN }}  fetch-depth: 0

semantic-releaseツールに必要な依存関係のみをインストールします:

- name: 必要なもののインストール  run: poetry install --only semver

最後のステップでは、一部のgitの設定を変更し、semantic-releaseの公開コマンドを実行します:

- name: Python Semantic Release  env:    GH_TOKEN: ${{ secrets.GH_TOKEN }}  run: |    set -o pipefail    # gitの詳細を設定    git config --global user.name "github-actions"    git config --global user.email "[email protected]"    # semantic-releaseを実行    poetry run semantic-release publish -v DEBUG -D commit_author="github-actions <[email protected]>"

git configを変更することにより、コミットするユーザーは「github-actions」になります。デバッグログ(標準出力)を使用してパブリッシュコマンドを実行し、commit_authorを明示的に「github-actions」に設定します。このコマンドの代わりに、直接semantic-releaseからGitHubアクションを使用することもできますが、パブリッシュコマンドの実行手順は非常に少なく、アクションは毎回プルする必要のあるDockerコンテナを使用しています。そのため、シンプルな実行ステップを作成することをお勧めします。

パブリッシュコマンドはコミットを作成するため、ワークフローが無限ループになる可能性があるかもしれません。しかし、心配しないでください。生成されるコミットは、別のGitHub Actionsワークフローの実行をトリガーしません。これは、GitHubが設定した制限によるものです。

パーソナルアクセストークン(PAT)の作成

パーソナルアクセストークンは、GitHub APIやコマンドラインを使用してGitHub Enterprise Serverに認証するためのパスワードの代わりとして使用することができます。パーソナルアクセストークンは、自分自身の代わりにGitHubリソースにアクセスするために使用されます。組織のリソースにアクセスする場合や、長期間使用される統合には、GitHub Appを使用する必要があります。詳細については、「アプリについて」を参照してください。

言い換えると、P ersonal A ccess T okenを作成し、GitHubアクションがそのsecretを保存して使用することで、私たちの代わりに特定の操作を実行できます。ただし、PATが危険にさらされると、GitHubリポジトリで悪意のある操作が行われる可能性があります。そのため、GitHub OAuth AppsやGitHub Appsを組織で使用することをお勧めします。このチュートリアルでは、GitHubアクションパイプラインが私たちの代わりに操作できるようにするために、PATを使用します。

GitHubのユーザーのSettingsセクションに移動し、Creating a Personal Access Tokenで要約された手順に従って、新しいアクセストークンを作成することができます。以下のウィンドウが表示されます:

Personal Access Token of an admin account with push access to the repos.

スコープを選択することで、トークンに付与する許可を定義します。私たちのユースケースでは、新しいPAT GH_TOKENrepoのパーミッションスコープを持つ必要があります。このスコープは、保護されたブランチにプッシュすることを許可し、保護されたブランチの設定でInclude administratorsが設定されていない場合に有効になります。

リポジトリ概要に戻り、Settingsメニューで、Secretsセクションの下に環境設定またはリポジトリ設定を追加することができます:

リポジトリシークレットは単一のリポジトリ(およびそこで使用されるすべての環境)に固有ですが、環境シークレットは環境に固有です。GitHubランナーは特定の環境で実行するように構成できるため、環境のシークレットにアクセスすることができます。これは、異なるステージ(例:DEV vs PROD)を考えると理にかなっていますが、このチュートリアルでは、リポジトリシークレットを使用します。

GitHubアクションフロー

いくつかのパイプライン(リンティング、テスト、リリース、ドキュメント)があるので、mainにコミットするときのアクションのフローについて考える必要があります。GitHubに固有のものも含めて、いくつかの注意点があります。

理想的には、mainにコミットすると、テストとリンティングのワークフローがトリガーされます。これらが成功した場合、バージョン番号のバンプがあるかどうかを検出するリリースワークフローを実行します。バンプがある場合、リリースワークフローは直接mainにプッシュし、バージョンを上げ、gitタグを追加し、リリースを作成します。例えば、公開されたリリースはドキュメントワークフローを実行することでドキュメントを更新するはずです。

Expected flow of actions

問題と考慮事項

  1. もし最後の段落を注意深く読んだり、上記のフローチャートを見たりした場合、mainブランチには2つのコミットがあることに気づいたかもしれません。1つ目は初期のコミット(つまりプルリクエストからのもの)であり、2つ目はリリースのためのものです。しかし、私たちのlint.ymlとtest.ymlはmainブランチへのプッシュイベントに反応するため、それらは2回実行されます!リソースを節約するために2回の実行を避ける必要があります。これを実現するために、バージョンのコミットメッセージに[skip ci]という文字列を追加することができます。ツールsemantic_releaseのpyproject.tomlファイルでカスタムのコミットメッセージを定義することができます。
# pyproject.toml...[tool.semantic_release]...commit_message = "{version} [skip ci]" # バージョンのコミットでciパイプラインのトリガーをスキップする...

2. 現在、pages.ymlワークフローはmainへのプッシュイベントで実行されています。ドキュメントの更新は新しいリリースがある場合にのみ行いたいかもしれません(ドキュメントでバージョンを参照しているかもしれません)。そのため、pages.ymlファイルでトリガーを変更することができます:

# pages.ymlname: Documentationon:  release:    types: [published]

ドキュメントのビルドには公開されたリリースが必要になります。

3. リリースワークフローはLinting & Testingワークフローの成功に依存する必要があります。現在、ワークフローファイルには依存関係が定義されていません。これらのワークフローを特定のブランチで定義したワークフローランの完了に依存させることができますが、workflow_runイベントに複数のworkflowsを指定した場合:

on:  workflow_run:    workflows: [Testing, Linting]    types:    - completed    branches:    - main

ワークフローのうちの1つだけが完了すれば良いです!これは私たちが望んでいることではありません。すべてのワークフローが完了(かつ成功)することを期待しています。その後、リリースワークフローが実行されるべきです。これは単一のワークフロー内のジョブ間の依存関係を定義する場合とは対照的です。この不整合と不足の詳細については、こちらの記事をご覧ください。

代わりに、パイプラインの順次実行を使用することができます:

このアイデアの大きな欠点は、a) パラレル実行が許可されないこと、そしてb) GitHubで依存関係グラフを表示できないことです。

解決策

上記の問題に対処する唯一の方法は、ワークフローをオーケストレータワークフローで組み立てることだと思います。

オーケストレータは、mainブランチにプッシュしたときにトリガーされます。

Testing & Lintingの両方のワークフローが成功した場合のみ、リリースワークフローが呼び出されます。これはneedsキーワードで定義されています。ジョブの実行(ワークフロー)に対してより詳細な制御をしたい場合は、ifキーワードも使用することを検討してください。ただし、この記事で説明されているような混乱を招く動作に注意してください。

ワークフローlint.ymltest.yml、およびrelease.ymlを別のワークフローから呼び出すために、トリガーを更新する必要があります:

# lint.yml---name: Lintingon:  pull_request:    branches:      - main  workflow_call:jobs:...

# test.yml---name: Testingon:  pull_request:    branches:      - main  workflow_call:jobs:...

# release.yml---name: Releaseon:  workflow_call:jobs:...

これで新しいワークフロー(リリース)は、品質チェックのためのワークフロー、この場合はlintingとtestingが成功した場合にのみ実行されるはずです。

バッジ

今回は、プラットフォームshields.ioを使用してバッジを作成します。

これは、バージョン、ビルドステータス、コードカバレッジなどの情報を表示するプロジェクトのバッジを生成するウェブサイトです。さまざまなテンプレートを提供し、外観のカスタマイズやカスタムバッジの作成が可能です。バッジは自動的に更新され、プロジェクトに関するリアルタイムの情報を提供します。

リリースバッジには、GitHubリリース(最新のSemVer)を選択しました:

バッジのマークダウンをコピーしてREADME.mdに追加できます:

GitHubのランディングページは、次のようになります ❤ (少し整理して説明を追加しました):

おめでとうございます!このチュートリアルのメインパートを完了しました!ソフトウェアのリリースを管理するための必須の手順を学びました。リリースの手動作成から始め、Conventional Commitsのパワーを活用してリリースプロセスをCIパイプラインを介して自動化しました。最後に、README.mdファイルにバッジを追加し、プロジェクトの最新バージョンをユーザーにわかりやすく簡潔に表示しました。これらのテクニックを使えば、効率的かつ効果的にソフトウェアのリリースを管理できます。

次のパートは最後のパートで、コンテナ化について説明します!

Johannes Schmidtのすべてのストーリー(およびVoAGIの他の数千人の作家のストーリー)を読む。会員費は直接…

johschmidt42.medium.com

ボーナス

Conventional Commitsの確認

定義された形式のコミットは、バージョニングに役立つことがわかりました。共同プロジェクトでは、デフォルトブランチのすべてのコミットにこの形式を強制したい場合があります。2つの人気のあるツールが開発者が従うための形式をサポートしています:

  • commitizen
  • commitlint

ただし、これらのツールは制約が多く、使用を避ける開発者もいます*。そのため、常にコミットが従うことを期待するだけではうまくいかないかもしれません。したがって、コンベンショナルコミット形式などのルールをサーバーサイドで強制することが合理的です!

*同様に、pre-commitフックも同様です。そのため、このシリーズでは除外しました。

残念なことに、現在(2023年5月)はGitHubでルールに基づいてコミットをブロックすることはできません。しかし、ブランチ保護ルールCIワークフローを使用して、できる限り近づけることができます。したがって、リポジトリでこの戦略を実行するために必要なものは次のとおりです:

  • 保護されたデフォルトブランチ(例:main)へのコミットは、プルリクエスト(PR)のコミットに制限されるべきです。
  • スクワッシュされたコミットのみが許可される*
  • スクワッシュしたプルリクエストをマージする際に表示されるデフォルトコミットメッセージは、プルリクエストのタイトルであるべきです

デフォルトブランチ(例:main)へのコミットがプルリクエスト(スクワッシュされたコミットのみ)を介してのみ行われる場合、amannn/action-semantic-pull-requestなどのGitHub Actionを使用して、プルリクエストのタイトルがConventional Commitsの仕様に一致することを確認できます。したがって、必要なパイプラインがすべて成功した場合に、PRブランチをスクワッシュしてマージすると、事前にGitHubアクションで確認されたPRタイトルが提案されるコミットメッセージになります。

*スクワッシュとマージ戦略は、フィーチャーブランチからメインブランチにコード変更をマージするための人気のあるメソッドであり、フィーチャーブランチの複数のコミットを1つのコミットにまとめます。これにより、各コミットが特定の変更を表す線形で一貫したGit履歴が作成されます。ただし、この方法には欠点もあります。開発プロセスを理解するために貴重なグラニュラーなコミット履歴が破棄されるためです。この情報を保持するためにリベースマージを使用することも可能ですが、ワークフローに複雑さをもたらすことがあります。この意味で、スクワッシュとマージ戦略は、そのシンプルさから好まれます。

ワークフロー

この戦略のためのGitHub Actionsワークフローを作成しましょう:

トリガーイベント pull_request_target についてはここで説明されています。私は推奨されるタイプ openededitedsynchronize を使用します。 GITHUB_TOKEN はアクションに対して env として渡されます。したがって、PRのタイトルが一般的なコミット形式で変更されるたびに、パイプラインがトリガーされます。PRのタイトルが一般的なコミット形式である場合にのみ成功します。

以下に注意してください。

アクションを最初に追加するPR内では、アクションが実行されないため、メインブランチにこの設定が必要です。また、PR内で設定を変更した場合、変更は現在のPRには反映されず、変更がメインブランチにある後続のPRにのみ反映されます。

したがって、最初にデフォルトブランチ main にこのワークフローを持つ必要があります。そうでないと、実際の動作を確認することはできません。

ブランチ保護ルール

次に、GitHubリポジトリの設定セクションでメインブランチのブランチ保護ルールを作成できます:

Branch Protection Rule for the main branch — Image by author

これにより、マージする前にPRがパスするステータスチェック(必要なワークフロー)のある必須PRが必要になります。

必要なワークフローは、プルリクエストイベントによってトリガーされ、必須のステータスチェックとして表示され、必要なワークフローが成功するまでプルリクエストのマージがブロックされます。

Required workflows — Image by author

組織の所有者は、プルリクエストで特定のワークフローを強制する能力を持っており、プルリクエストにステータスチェックを要求するなどの機能を活用できます。残念ながら、この機能は組織にのみ利用可能であり、個人アカウントではアクティブ化できないため、マージをブロックすることはできません。

*プライベートリポジトリに対しては、GitHub TeamまたはEnterprise組織アカウントに移動するまで、これらのルールは強制されませんので、ご注意ください!

スカッシュ&マージ戦略

最後に、PRオプションを設定して、スカッシュ&マージボタンを選択した場合にPRのタイトルをデフォルトのコミットメッセージとして使用できるようにします:

Default commit message when squash and merge — Image by author

これにより、次のようなウィンドウが表示されます:

Sqash & merge dialog in a PR — Image by author

開発者はマージ中にタイトルの名前を変更する可能性があるため、この戦略は回避される可能性があります!

Githubではまだ完全に一般的なコミットを保証することはできませんが、できるだけ近づけるように努力するべきです。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

人工知能

「トリントの創設者兼CEO、ジェフ・コフマンへのインタビューシリーズ」

ジェフ・コーフマンは、ABC、CBS、CBCニュースで30年のキャリアを持った後、Trintの創設者兼CEOとなりましたジェフは手作業の...

データサイエンス

「3つの質問:ロボットの認識とマッピングの研磨」

MIT LIDSのLuca CarloneさんとJonathan Howさんは、将来のロボットが環境をどのように知覚し、相互作用するかについて議論し...

人工知能

ピーター・マッキー、Sonarの開発者担当責任者-インタビューシリーズ

ピーター・マッキーはSonarのDeveloper Relationsの責任者です Sonarは、悪いコードの1兆ドルの課題を解決するプラットフォー...

人工知能

ファイデムのチーフ・プロダクト・オフィサー、アルパー・テキン-インタビューシリーズ

アルパー・テキンは、FindemというAI人材の獲得と管理プラットフォームの最高製品責任者(CPO)ですFindemのTalent Data Clou...

人工知能

ジョシュ・フィースト、CogitoのCEO兼共同創業者 - インタビューシリーズ

ジョシュ・フィーストは、CogitoのCEO兼共同創業者であり、感情と会話AIを組み合わせた革新的なプラットフォームを提供するエ...

人工知能

「アナコンダのCEO兼共同創業者、ピーターウォングによるインタビューシリーズ」

ピーター・ワンはAnacondaのCEO兼共同創設者ですAnaconda(以前はContinuum Analyticsとして知られる)を設立する前は、ピー...