独自のプロジェクトでプライベートGoモジュールを使用する方法
著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
Goのエコシステムの有益な側面の1つは、多数のモジュールがオープンソースであることです。 それらはオープンソースであるため、自由にアクセス、調査、使用、および学習することができます。 ただし、独自のビジネスロジックを社内に保持するなど、さまざまな理由でプライベートGoモジュールを作成する必要がある場合があります。
このチュートリアルでは、プライベートGoモジュールを公開し、プライベートモジュールにアクセスするための認証を設定し、プロジェクトでプライベートGoモジュールを使用します。
前提条件
- Go version 1.16 or greater installed. To set this up, follow the How To Install Go tutorial for your operating system.
- Goモジュールの配布方法チュートリアルにあるGoモジュールの配布についての理解。
- Gitの使用方法:リファレンスガイドに従って取得できるGitの知識。
- 公開されたプライベートモジュール用の
mysecret
という名前の空のプライベートGitHubリポジトリ。 開始するには、GitHubのドキュメントに従ってリポジトリを作成します。 - リポジトリから読み取るためのアクセス権を持つGitHubパーソナルアクセストークン。 これを使用して、Goがプライベートリポジトリにアクセスできるようにします。
プライベートモジュールの配布
多くのプログラミング言語とは異なり、Goは中央パッケージサーバーではなくリポジトリからモジュールを配布します。 このアプローチの利点の1つは、プライベートモジュールの公開がパブリックモジュールの公開と非常に似ていることです。 完全に独立したプライベートパッケージサーバーを必要とする代わりに、Goプライベートモジュールはプライベートソースコードリポジトリを介して配布されます。 ほとんどのソースコードホスティングオプションはこれをすぐにサポートするため、追加のプライベートサーバーを設定する必要はありません。
プライベートモジュールを使用するには、プライベートGoモジュールにアクセスできる必要があります。 このセクションでは、チュートリアルの後半で別のGoプログラムからプライベートモジュールにアクセスするために使用できるプライベートモジュールを作成して公開します。
新しいプライベートGoモジュールを作成するには、まず、それが存在するプライベートGitHubリポジトリのクローンを作成します。 前提条件の一部として、GitHubアカウントにmysecret
という名前のプライベートな空のリポジトリを作成しました。これは、プライベートモジュールに使用するリポジトリです。 このリポジトリは、コンピュータのどこにでも複製できますが、多くの開発者はプロジェクト用のディレクトリを持っている傾向があります。 このチュートリアルでは、projects
という名前のディレクトリを使用します。
projects
ディレクトリを作成し、次の場所に移動します。
mkdir projects cd projects
projects
ディレクトリから、git clone
を実行して、プライベートmysecret
リポジトリをコンピュータに複製します。
git clone [email protected]:your_github_username/mysecret.git
Gitはモジュールのクローンを作成したことを確認し、空のリポジトリのクローンを作成したことを警告する場合があります。 もしそうなら、これはあなたが心配する必要があるものではありません:
OutputCloning into 'mysecret'... warning: You appear to have cloned an empty repository.
次に、cd
を使用して、複製した新しいmysecret
ディレクトリに移動し、go mod init
をプライベートリポジトリの名前とともに使用して、新しいGoモジュールを作成します。
cd mysecret go mod init github.com/your_github_username/mysecret
モジュールが作成されたので、別のプロジェクトから使用できる関数を追加します。 nano
またはお気に入りのテキストエディタを使用して、mysecret.go
などのリポジトリと同じ名前のファイルを開きます。 名前は重要ではなく、何でもかまいませんが、リポジトリと同じ名前を使用すると、新しいモジュールで作業するときに最初に調べるファイルを簡単に決定できます。
nano mysecret.go
mysecret.go
ファイルで、リポジトリと同じ名前のパッケージに名前を付け、SecretProcess
関数を追加して、呼び出されたときにRunning the secret process!
行を出力します。
projects / mysecret / mysecret.go
package mysecret import "fmt" func SecretProcess() { fmt.Println("Running the secret process!") }
プライベートモジュールが作成されたので、他の人が使用できるようにプライベートリポジトリに公開します。 プライベートリポジトリでは最初にしかアクセスできないため、プライベートモジュールにアクセスできるユーザーを制御できます。 自分へのアクセスを制限することもできますが、友人や同僚へのアクセスを許可することもできます。
プライベートGoモジュールとパブリックGoモジュールはどちらもソースリポジトリであるため、プライベートGoモジュールの公開は、パブリックGoモジュールの公開と同じプロセスに従います。 新しいモジュールを公開するには、git add
コマンドを使用して現在のディレクトリで変更をステージングし、git commit
コマンドを使用してそれらの変更をローカルリポジトリにコミットします。
git add . git commit -m "Initial private module implementation"
最初のコミットが成功したというGitからの確認と、コミットに含まれるファイルの概要が表示されます。
Output[main (root-commit) bda059d] Initial private module implementation 2 files changed, 10 insertions(+) create mode 100644 go.mod create mode 100644 mysecret.go
残っているのは、変更をGitHubリポジトリに移動することだけです。 パブリックモジュールと同様に、git push
コマンドを使用してコードを公開します。
git push
次に、Gitは変更をプッシュし、プライベートリポジトリにアクセスできるすべての人が変更できるようにします。
git push origin main Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Delta compression using up to 8 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (4/4), 404 bytes | 404.00 KiB/s, done. Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 To github.com:your_github_username/mysecret.git * [new branch] main -> main
パブリックGoモジュールと同様に、プライベートGoモジュールにバージョンを追加することもできます。 Goモジュールの配布方法チュートリアルの新しいモジュールバージョンの公開セクションには、これを行う方法に関する情報が含まれています。
このセクションでは、SecretProcess
関数を使用して新しいモジュールを作成し、それをプライベートmysecret
GitHubリポジトリに公開して、プライベートGoモジュールにしました。 ただし、別のGoプログラムからこのモジュールにアクセスするには、モジュールにアクセスする方法を認識できるようにGoを構成する必要があります。
GotoAccessプライベートモジュールの構成
Goモジュールは通常、ソースコードリポジトリから配布されますが、Goチームはいくつかの中央Goモジュールサービスも実行して、元のリポジトリに何かが起こった場合にモジュールが存在し続けるようにします。 デフォルトでは、Goはこれらのサービスを使用するように構成されていますが、プライベートモジュールをダウンロードしようとすると、これらのモジュールにアクセスできないため、問題が発生する可能性があります。 一部のインポートパスがプライベートであり、中央のGoサービスを使用してはならないことをGoに通知するには、GOPRIVATE
環境変数を使用できます。 GOPRIVATE
環境変数は、インポートパスプレフィックスのコンマ区切りのリストであり、検出されると、Goツールは中央サービスを経由せずに直接アクセスしようとします。 そのような例の1つは、作成したばかりのプライベートモジュールです。
プライベートモジュールを使用するには、GOPRIVATE
変数に設定して、プライベートと見なすパスをGoに指示します。 GOPRIVATE
変数値を設定するときに選択できることがいくつかあります。 1つのオプションは、GOPRIVATE
をgithub.com
に設定することです。 ただし、これは、github.com
でホストされているモジュール(自分のものではないものも含む)の中央サービスを使用しないようにGoに指示するため、探しているものではない可能性があります。
次のオプションは、GOPRIVATE
をgithub.com/your_github_username
などの独自のユーザーパスのみに設定することです。 これにより、すべてのGitHubをプライベートと見なすという問題は解決しますが、ある時点で、作成したパブリックモジュールがあり、Goモジュールミラーを介してダウンロードしたい場合があります。 これを行うことは問題を引き起こさず、完全に合理的なオプションですが、さらに具体的にするオプションもあります。
最も具体的なオプションは、GOPRIVATE
をモジュールのパスに正確に一致するように設定することです(例:github.com/your_github_username/mysecret
)。 これにより、前のオプションの両方の問題が解決されますが、次に示すように、各プライベートリポジトリをGOPRIVATE
に個別に追加する必要があるという問題も発生します。
GOPRIVATE=github.com/your_github_username/mysecret,github.com/your_github_username/othersecret
あなた自身のための最良の選択肢を選ぶことはあなたの状況で賛否両論を比較検討することの問題です。
現在、プライベートモジュールは1つしかないため、値には完全なリポジトリ名を使用します。 現在の端末でGOPRIVATE=github.com/your_github_username/mysecret
環境変数を設定するには、次のエクスポートコマンドを使用します。
export GOPRIVATE=github.com/your_github_username/mysecret
設定されていることを再確認したい場合は、env
コマンドとgrep
を使用して、GOPRIVATE
の名前を確認できます。
env | grep GOPRIVATE
OutputGOPRIVATE=github.com/your_github_username/mysecret
Goはモジュールがプライベートであることを認識していますが、モジュールを使用するにはまだ十分ではありません。 プライベートモジュールを別のモジュールにgo get
しようとすると、次のようなエラーが表示される可能性があります。
go get github.com/your_github_username/mysecret
Outputgo get: module github.com/your_github_username/mysecret: git ls-remote -q origin in /Users/your_github_username/go/pkg/mod/cache/vcs/2f8c...b9ea: exit status 128: fatal: could not read Username for 'https://github.com': terminal prompts disabled Confirm the import path was entered correctly. If this is a private repository, see https://golang.org/doc/faq#git_https for additional information.
このエラーメッセージは、Goがモジュールをダウンロードしようとしましたが、まだアクセスできない何かが発生したことを示しています。 モジュールのダウンロードにはGitが使用されているため、通常は資格情報の入力を求められます。 ただし、この場合、GoはGitを呼び出しており、プロンプトを表示することはできません。 この時点で、モジュールにアクセスするには、Gitがすぐに入力せずにクレデンシャルを取得する方法を提供する必要があります。
HTTPS用のプライベートモジュールクレデンシャルの提供
あなたに代わってログインする方法をGitに伝える1つの方法は、.netrc
ファイルです。 ユーザーのホームディレクトリにある.netrc
ファイルには、さまざまなホスト名と、それらのホストのログイン資格情報が含まれています。 Gitを含む多くのツールで広く使用されています。
デフォルトでは、go get
がモジュールをダウンロードしようとすると、最初にHTTPSを使用しようとします。 ただし、前の例で示したように、ユーザー名とパスワードの入力を求めるプロンプトを表示することはできません。 Gitに資格情報を与えるには、ホームディレクトリにgithub.com
を含む.netrc
が必要です。
Linux、MacOS、またはWindows Subsystem for Linux(WSL)で.netrc
ファイルを作成するには、ホームディレクトリ(~/
)で.netrc
ファイルを開いて、編集できるようにします。 :
nano ~/.netrc
次に、ファイルに新しいエントリを作成します。 machine
の値は、資格情報を設定するホスト名である必要があります。この場合はgithub.com
です。 login
の値は、GitHubのユーザー名になります。 最後に、password
の値は、作成したGitHubパーソナルアクセストークンである必要があります。
〜/ .netrc
machine github.com login your_github_username password your_github_access_token
必要に応じて、エントリ全体をファイルの1行に配置することもできます。
〜/ .netrc
machine github.com login your_github_username password your_github_access_token
注:ソースコードホスティングに Bitbucket を使用している場合は、bitbucket.org
に加えてapi.bitbucket.org
の2番目のエントリも追加する必要があります。 以前は、Bitbucketは複数のタイプのバージョン管理のホスティングを提供していたため、GoはAPIを使用して、ダウンロードを試みる前にリポジトリのタイプを確認していました。 これはもはや当てはまりませんが、APIチェックはまだ存在しています。 この問題が発生した場合、エラーメッセージの例は次のようになります。
go get bitbucket.org/your_github_username/mysecret: reading https://api.bitbucket.org/2.0/repositories/your_bitbucket_username/protocol?fields=scm: 403 Forbidden server response: Access denied. You must have write or admin access.
プライベートモジュールをダウンロードしようとしたときに403 Forbidden
エラーが表示された場合は、Goが接続しようとしているホスト名を再確認してください。 api.bitbucket.org
などの別のホスト名を示している可能性があります。
これで、プライベートモジュールのダウンロードにHTTPS認証を使用するように環境が設定されました。 GoとGitがモジュールをダウンロードしようとするデフォルトの方法はHTTPSですが、代わりにSSHを使用するようにGitに指示することもできます。 HTTPSの代わりにSSHを使用すると便利な場合があるため、プライベートモジュールのプッシュに使用したのと同じSSHキーを使用できます。 また、個人用アクセストークンを作成したくない場合は、 CI /CD環境をセットアップするときにデプロイキーを使用できます。
SSH用のプライベートモジュールクレデンシャルの提供
HTTPSの代わりにプライベートGoモジュールの認証方法としてSSHキーを使用するために、GitはinsteadOf
と呼ばれる構成オプションを提供します。 insteadOf
オプションを使用すると、すべてのGitリクエストのリクエストURLとしてhttps://github.com/
を使用する代わりに、ssh://[email protected]/
を使用することをお勧めします。
Linux、MacOS、およびWSLでは、この構成は.gitconfig
ファイルにあります。 このファイルは、コミットの電子メールアドレスと名前も構成されているため、既にご存知かもしれません。 ファイルを編集するには、nano
またはお気に入りのテキストエディタを使用して、ホームディレクトリにある~/.gitconfig
ファイルを開きます。
nano ~/.gitconfig
ファイルを開いたら、次の例のように、ssh://[email protected]/
のurl
セクションを含めるようにファイルを編集します。
〜/ .gitconfig
[user] email = [email protected] name = Sammy the Shark [url "ssh://[email protected]/"] insteadOf = https://github.com/
user
セクションに対するurl
セクションの順序は重要ではありません。また、url
以外にファイルに何もない場合でも心配する必要はありません。 ]追加したセクション。 user
セクション内のemail
フィールドとname
フィールドの順序も重要ではありません。
この新しいセクションは、https://github.com/
で始まる使用するURLの前に、代わりにssh://[email protected]/
を置き換える必要があることをGitに通知します。 GoはデフォルトでHTTPSを使用するため、これはgo get
コマンドにも影響します。 プライベートモジュールを例として使用すると、これはGoがgithub.com/your_github_username/mysecret
インポートパスをURLhttps://github.com/your_github_username/mysecret
に変換することを意味します。 GitがこのURLに遭遇すると、URLがinsteadOf
によって参照されるhttps://github.com/
プレフィックスと一致することがわかり、結果のURLがssh://[email protected]/your_github_username/mysecret
に変わります。
ssh://git@
URLがそのホストでも機能する限り、これと同じパターンをGitHub以外のドメインに使用できます。
このセクションでは、SSHを使用して.gitconfig
ファイルを更新し、url
セクションを追加して、GoモジュールをダウンロードするようにGitを構成しました。 プライベートモジュールの認証が設定されたので、Goプログラムで使用するためにアクセスできます。
プライベートモジュールの使用
前のセクションでは、HTTPS、SSH、またはその両方を介してプライベートGoモジュールにアクセスするようにGoを構成しました。 Goがプライベートモジュールにアクセスできるようになったので、過去に使用した可能性のある他のパブリックモジュールと同様に使用できます。 このセクションでは、プライベートモジュールを使用する新しいGoモジュールを作成します。
projects
などのプロジェクトに使用するディレクトリで、mkdir
コマンドを使用して、新しいプロジェクト用にmyproject
という名前のディレクトリを作成します。
mkdir myproject
ディレクトリが作成されたら、cd
を使用してディレクトリに移動し、 [など、プロジェクトが存在するリポジトリURLに基づいて、プロジェクトのgo mod init
を使用して新しいGoモジュールを初期化します。 X199X]。 プロジェクトを他のリポジトリにプッシュする予定がない場合、モジュール名はmyproject
または他の名前にすることができますが、共有されるほとんどのモジュールで完全なURLが必要になるため、完全なURLを使用することをお勧めします。 。
cd myproject go mod init github.com/your_github_username/myproject
Outputgo: creating new go.mod: module github.com/your_github_username/myproject
次に、nano
またはお気に入りのテキストエディタでmain.go
を開いて、プロジェクトの最初のコードファイルを作成します。
nano main.go
ファイル内で、プライベートモジュールを呼び出す最初のmain
関数を設定します。
projects / myproject / main.go
package main import "fmt" func main() { fmt.Println("My new project!") }
今すぐプロジェクトを実行し、すべてが正しく設定されていることを確認するには、go run
コマンドを使用して、main.go
ファイルを提供します。
go run main.go
OutputMy new project!
次に、パブリックモジュールの場合と同様に、go get
を使用して、新しいプロジェクトの依存関係としてプライベートモジュールを追加します。
go get github.com/your_github_username/mysecret
go
ツールは、プライベートモジュールのコードをダウンロードし、最新のコミットハッシュとそのコミットの時刻に一致するバージョン文字列を使用して依存関係として追加します。
Outputgo: downloading github.com/your_github_username/mysecret v0.0.0-20210920195630-bda059d63fa2 go get: added github.com/your_github_username/mysecret v0.0.0-20210920195630-bda059d63fa2
最後に、main.go
ファイルを再度開き、それを更新して、main
関数のプライベートモジュールのSecretProcess
関数への呼び出しを追加します。 また、import
ステートメントを更新して、github.com/your_github_username/mysecret
プライベートモジュールもインポートとして追加する必要があります。
projects / myproject / main.go
package main import ( "fmt" "github.com/your_github_username/mysecret" ) func main() { fmt.Println("My new project!") mysecret.SecretProcess() }
プライベートモジュールで実行されている最終的なプロジェクトを確認するには、main.go
ファイルをパラメーターとして指定しながら、go run
コマンドを再度使用します。
go run main.go
元のコードのMy new project!
行が表示されますが、インポートしたmysecret
モジュールのRunning the secret process!
行も表示されます。
OutputMy new project! Running the secret process!
このセクションでは、go init
を使用して、以前に公開したプライベートモジュールにアクセスするための新しいGoモジュールを作成しました。 モジュールを作成したら、go get
を使用して、パブリックGoモジュールの場合と同じようにプライベートモジュールをダウンロードします。 最後に、go run
を使用して、プライベートモジュールを使用してGoプログラムをコンパイルおよび実行しました。
結論
このチュートリアルでは、プライベートGoモジュールを作成して公開しました。 また、プライベートGoモジュールにアクセスするためにHTTPS認証とSSH認証の両方を設定します。 最後に、新しいプロジェクトでプライベートモジュールを使用しました。
Goモジュールの詳細については、Goプロジェクトに一連のブログ投稿があり、Goツールがモジュールとどのように相互作用して理解するかを詳しく説明しています。 Goプロジェクトには、GoモジュールリファレンスにGoモジュールに関する非常に詳細で技術的なリファレンスもあります。
GOPRIVATE
環境変数に加えて、プライベートGoモジュールを操作するときに使用できる変数が増えます。 詳細については、Goモジュールリファレンスのプライベートモジュールセクションを参照してください。
.netrc
ファイルの詳細を調べることに興味がある場合は、.netrcのGNU Webサイトに、使用可能なすべてのキーワードのリストが含まれています。 git-configドキュメントには、使用可能な他のオプションに加えて、使用したinsteadOf
構成オプションがどのように機能するかについての詳細も含まれています。
このチュートリアルは、 DigitalOcean How to Code inGoシリーズの一部でもあります。 このシリーズでは、Goの初めてのインストールから、言語自体の使用方法まで、Goに関する多くのトピックを取り上げています。