😎

CDKコントリビュートへの道:CONTRIBUTING.md読解編

に公開

以下に記載したようにgithubからコントリビュートを誘われている。

また、以前lambda power toolsのコントリビューも試みたが、登録したissueがメンテナーの確認待ちで動かないので別件も進めてみる。

プロジェクトの選択

今回はCDKです。

感想

すごく長くて内容を忘れそう(というか書いた直後にも忘れている)ので読んだ感想だけ残しておきます

  • コミットの慣習というまとまった情報があることを初めて知った.https://www.conventionalcommits.org/en/v1.0.0/ コミットメッセージの形式を一定のルールに従って書く方法で、目的は、変更内容を機械的に解析・分類できるようにすることらしい。つい書きがちな以下などの不要な情報をなくして適切なコミットを書くときにはルールが有ると助かる。

    feat: 機能について説明をしてください (「追加した」「変更した」等のPRの作業は避けてください)
    fix: バグについて記載してください (解決策について記載しないでください)

  • ロゼッタという仕組みで、typescriptで書かれたサンプルコードを多言語に変換しているらしい。すごい便利!
  • プリリクエストを出すとバッジがもらえるらしい。ほしい!

プロジェクトについて学ぶ

まずはコントリビュートのお作法を勉強。
くっそ長いけど頑張って読む。

AWS Cloud Development Kit へのコントリビュート

AWS Cloud Development Kit (AWS CDK) オープンソースのソフトウェア開発フレームワークで、コントリビュートできます.我々はコミュニティからのコントリビューションを重要視しており、それはAWS CDKの開発を促進します。このドキュメントでは以下を解説します。それは「コントリビューションの始め方」「効果のあるコントリビューションか確認する方法」「スムーズに事を進める方法」です。

AWS CDKはApache licenseで開発されています。あなたが提出したコードも同様になります。

コントリビュートとはなんですか?

コントリビュートとはコミュニティによるAWS CDKへの改善や機能追加のことを指します。aws-cdkレポジトリでコントリビューションでき、コントリビューションには以下を含みます。

  • 新機能 - 既存あるいは新しいAWSサービスの、既存あるいは新しいL2コンストラクタの追加.
  • バグ修正 - 問題に対処して改善して機能を向上したりエラーを修正します.
  • ドキュメント - ドキュメントを改善します。例の追加、読みやすさの向上、既存コンテンツの更新などがあります.
  • テスト - コード・カバレッジを広げ、安定性を確実にするためにテストを追加・改善します.
  • リファクタリング - 動作を変えずにコードの構造やパフォーマンスを改善します.

コントリビューションはそのスコープとサイズで メジャーマイナー に分けられます。

  • メジャー - 新しいL2コンストラクトの追加. AWS CDKの動作の変更. 破壊的変更を含む既存のAWS CDKの機能更新.
  • マイナー - バグ修正. 既存のL2コンストラクトの改善. その他の動作変更のないテストやドキュメントの更新.

コントリビューションの仕組み

以下の図は、コントリビュートを作ってから完了するまでの仕組みを示します.

コントリビュートする場所

コントリビュートは様々なチャネルで受け付けられ、例えばaws/aws-cdkへの直接のPRなどです。 しかし、変更点によってはそれは理想的ではない可能性があります。aws-cdkチームの活動量は限られているため、自分自身でコードを使いたいだけであれば、自分のパッケージを公開することで、aws-cdkチームのレビューやフィードバックのサイクルを避ける方が良いかもしれません。 とはいえ、多くのCDKユーザに望まれている変更の場合は、awsのコアパッケージに含む必要があります。

我々のコントリビュートの観点は以下です。

  1. シグナル - 対処するissueや関連issueがある. issueが多くの賛同を得ている、コメントや+1リアクションがされている。
  2. サイズ - 自己完結的な範囲で収まっていますか? 意味をなす最小単位に分割されていますか?
  3. 優先度 - カバレッジの優先度が高いサービスに関するissueや機能追加に関する内容ですか? IAM, EC2, Lambda, そして ECSはAWSで最もよく使われるサービスです。
  4. 品質 - design patternsを参照し、テストカバレッジやベストプラクティスや、aws-cdkレポジトリのコードのベストプラクティス等のガイドラインを考慮しましたか? aws-cdkレポジトリで一般的に使われているパターンに従うように努め、不必要にそれらの関連を逸脱していませんか?
  5. 破壊的変更 - 既存のユーザアプリケーショに影響するリスクについて説明していますか? 特に、コードの変更が必要なもの、リソース変更につながるもの、ダウンタイムにつながるものはありませんか?

コントリビュートの価値を提示する

プルリクエストを作るときは、関連する基準の根拠を説明に含めることを忘れないでください。 レビューアーに対してあなたのプルリクエストを受け入れるべき理由を明確にするためです. 特に、この機能がcore aws-cdkに含まれ、cdkチームによってメンテナンスされるべき根拠が必要です. 機能を個別に提供することができませんか? 機能がコアフレームワークに含まれるべきと確信できずプルリクエストを閉じる場合に、私達を納得させるためにできることがあります.

  1. 適切なissueとその他のユーザの関心のリンクを記載しましょう.
  2. コントリビューションが対応する現在の良くない状況のユースケースを説明しましょう.
  3. 同じ機能を提供するその他の先行技術やサードパーティパッケージのリンクを記載しましょう.
  4. 手順を繰り返し、コントリビュートが考え抜かれ、安定していることを確認しましょう.
  5. その他の選択肢を提示し、なぜそれを選択しないか説明しましょう.

この情報でレビューアはあなたのコントリビュートを受け入れるべきか明確に示します. それでもレビューアが必要性や有効性を認めない場合は別の方法を考える必要があります.

自分自身のパッケージを公開する

機能がaws-coreパッケージに含まれるべきであることを最も強くCDKチームに伝えることができます. npm, PyPI, Maven Central, NuGet, and GitHub (for Go)などで公開され、良いドキュメント、明確な目的、アクティブなユーザグループを持つということは、有用でありaws-cdkコアにいれることを考慮すべきであることを示しています。いれるべきであることを示しています.

信頼とサードパーティパッケージ

コントリビューターは自分のパッケージでコントリビュートを公開したくない場合があります。よく見かける議論ですが、組織が仕様を許可するパッケージを制限していて、信頼されたソースからのパッケージのみを許可しているということです. ソフトウェアの依存チェーンにおいて信頼は重要であり、コントリビュートにおいても考慮します. しかし全てのaws-cdkチームが所有することはできません.

とはいえ、「信頼」は「AWS が所有しているから大丈夫」というほど白黒はっきりしたものではありません。AWS リソースの生成に利用しているパッケージを信頼する最良の方法は、アプリケーションの出力に対して ポリシー検証 を行い、自分や組織にとって重要なルールに準拠している事を確認することです。

サードパーティパッケージ管理

リポジトリとツールチェーンの公開の手間を避けるために自分たちのパッケージを公開したくないという声もよく耳にします。この声に答えるために作業支援のツールを紹介します。

  1. Projen - 共通リポジトリと公開設定が抽象化されたツールで、CDK コンストラクト ライブラリ専用のコンストラクトを備えています.
  2. Publib - 複数のレポジトリにパッケージを公開するツールチェーン. 多くがprojenに含まれていて、publibを直接使うよりはprojenを使うことをお勧めしますが、場合によってはpublibが有用な場合もあります.
  3. Construct Hub - NPM に公開されているすべてのコンストラクトライブラリのインデックスです。コンストラクトライブラリを公開すると、自動的にドキュメントが生成され、Construct Hub に公開されます.

クイックスタート

セットアップ

aws-cdk レポジトリをあなたのアカウントにフォークしてください. https://github.com/aws/aws-cdk/fork
Note: 大きなファイル変更時には git lfs install でGit LFS をインストールしてください.

フォークしたレポジトリをクローンします.

$ git clone https://github.com/{your-account}/aws-cdk.git
$ cd aws-cdk
$ yarn install

プルリクエストを作る前に以下を実施します。

  • コードを変更する
  • 単体テストを書く
  • 統合テストを書く (aws-cdk/packages/@aws-cdk-testing/)
  • コミットし、プッシュする

aws-cdkリポジトリをビルドします.

$ npx lerna run build --skip-nx-cache

テスト

変更したモジュールの単体テストを実行します. 例えば aws-lambda 等です。

$ cd aws-cdk/packages/aws-cdk-lib
$ yarn test aws-lambda

変更したモジュールの統合テストを実行します. 例えば aws-lambda 等です。

$ cd aws-cdk/packages/@aws-cdk-testing/framework-integ
$ yarn integ test/aws-lambda/test/integ.lambda.js --update-on-failed

READMEのサンプルを変更した場合は、以下のコマンドでコンパイル動作を確認します。examples compile with:

$ /bin/bash ./scripts/run-rosetta.sh

リンク

コードの変更を CDK アプリに対してテストする場合は、アプリを作成し、ローカル CDK をリンクします.

$ mkdir cdkApp # in parent dir of aws-cdk
$ cd cdkApp
$ npx cdk init app --language typescript
$ npx cdk --version # shows the latest CDK version e.g. 2.155.0 (build 34dcc5a)
$ ../aws-cdk/link-all.sh # link the aws-cdk repo with your cdkApp
$ npx cdk --version # verify linked cdk version 0.0.0
# Define the resource that uses your aws-cdk changes in cdkApp lib folder
$ npx cdk deploy # deploy successfully

ここまでできたら次はプルリクエストを作ります。

作業を開始する

クイックスタートに追加で詳細を補足説明します。
AWS CDKリポジトリをローカルで準備する方法を記載します.
Gitpodを使うと簡単に環境が作れます.Gitpod section を見てください.

準備

CDKをインストールする前に以下の事前条件をトトの手ておく必要があります.

最初に以下からレポジトリをフォークします https://github.com/aws/aws-cdk/fork, その後localにcloneします.

$ git clone https://github.com/{your-account}/aws-cdk.git
$ cd aws-cdk
$ yarn install

開発には Visual Studio Code を使うことをお勧めします.
一貫性と品質を保つため、ESLint を使いますのでインストールすることをお勧めします。
ESLint extension でも良いです.

Windowsを開発環境とする場合はパフォーマンスと互換性の問題があります。その場合はGitpodAmazon CodeCatalyst DevEnv を代わりに使うことを検討してください.

レポジトリレイアウト

AWS CDK は NPM プロジェクトで typescript で実装されています.また、lernaを使ったモノレポで構成されているという特徴もあります.
これらの技術を知らない場合は、学ぶことでAWS CDKのコードベースを深く理解できます. しかし単純なコントリビュートの場合は必須ではありません.

CDK は jsii をビルドシステムとして使います. jsii で TypeScript準拠のソースコードを記述し、Java, .NET, Python and Go 等の多言語ライブラリを作ることができます.

レポジトリは packages/ を持ちCDK の パブリックモジュールを含みます. IAMモジュールに関するコードは packages/aws-cdk-lib/aws-iam にあります.
レポジトリは tools/ も持ち ここにはprivate npm packages等のカスタムビルドモジュールを含みます.

aws-cdk-libをビルドする

レポジトリ内のすべてのパッケージのビルドには数分掛かります. 全てのテストを実行すると20分程かかります.
ほとんどのコントリビュートは単一のパッケージのみを必要とします. ビルドするには以下のコマンドを実行します.

$ npx lerna run build --scope=aws-cdk-lib

Note: lerna はデフォルトでlocal cacheを使います. ビルドが失敗したら修正してリビルドします。この時前回成功したステップはビルドしません。

Note: ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory というエラーが起きたら export NODE_OPTIONS="--max-old-space-size=8192" で使えるメモリを増やすことを試みてください.

この時点で、モジュール実行によりaws-cdk-libのビルドとテストをすることができています。

$ cd packages/aws-cdk-lib
$ yarn build
$ yarn test

開発中に時間を節約するには, yarn watch を使うことができます. aws-cdk-lib のビルド状態の一部をメモリ内に保持し、変更を加えるたびに段階的に再構築することができます.ただし、レポジトリ全体をビルドする場合は次のコマンドで可能です.

cd <root of the CDK repo>
npx lerna run build

さてCDKにコントリビュートする準備ができました. Pull Requests を見て変更をする方法を知りプルリクエストを出してください.

キャッシュを使わないでビルドしたいときは--skip-nx-cache フラグを付けましょう.

$ npx lerna run build --skip-nx-cache

パック

上記で説明したようにAWS CDKは多言語対応するためにjsiiを使います. つまりターゲットとする言語のアーティファクトが作られます。
パッキングとは、様々なターゲット言語でCDKコードを生成し、それぞれのパッケージマネージャーに公開するためにパッケージ化する作業です。新機能をテストするため、あるいはパッケージ化の失敗を再現するために、時折、これらのコードを生成する必要があります。
特定のモジュールをパッケージ化するには、次のようにaws-cdk-libモジュールを使います。

$ cd <root-of-cdk-repo>
$ docker run --rm --net=host -it -v $PWD:$PWD -w $PWD jsii/superchain:1-buster-slim
docker$ cd packages/aws-cdk-lib
docker$ ../../scripts/foreach.sh --up yarn run package
docker$ exit

dist/ フォルダに言語ごとのアーティファクトを保持します.artifacts.

Dev Container

AWS CDK は 全ての依存関係が事前にインストールされた VS Code の Dev Container 環境を提供しています.
VS Codeの設定にはsetup instructions に従ってください。

VS Code を設定すると Dev Container で aws-cdk レポジトリを開くように求められます. あるいは VS Codeのコマンドパレットから "Dev Containers: Reopen in Container" を VS Code のコマンドパレットから開くこともできます.

Gitpod

Gitpod を使うこともできます。その場合は以下をクリックしてください。
Open in Gitpod

これにより pre-built が扱える新しいGitpodワークスペースが始まります.
Getting Started に従って開発を進めることができます.

Gitpod は50時間/月まで無料です。作業が終わったら止めることをお忘れなく。いつでも作業を再開できますしリビルドの必要もありません.

Gitpod を使う場合だけですが、GitpodでAWSを使う最良の方法は AWS IAM Identity Center(successor to AWS Single Sign-On). Install AWS CLI v2 を使うことで、以下のように設定できます:

# make sure AWS CLI v2 is in your $PATH
$ aws --version
# configure the AWS profile with SSO
$ aws configure sso
# login and authenticate
$ aws sso login
# verify your current identity
$ aws sts get-caller-identity

詳しくはこちらを参照してください this document.

あるいはターミナルからAWS credentialsを使ってください persisting environment variables.

eval $(gp env -e AWS_ACCESS_KEY_ID=XXXXXXXXX)
eval $(gp env -e AWS_SECRET_ACCESS_KEY=YYYYYYY)
eval $(gp env -e AWS_DEFAULT_REGION=ZZZZZZZZ)
eval $(gp env -e)

Amazon CodeCatalyst Dev Environments

クラウドベースの Amazon CodeCatalyst を使うこともでき、お好みのIDEでgithubレポジトリのチェックアウトができます.

Dev Envを実行すると aws-cdk-libframework-integ が設定されます:

$ yarn install
$ NODE_OPTIONS=--max-old-space-size=8192 npx lerna run build --scope=aws-cdk-lib --scope=@aws-cdk-testing/framework-integ

Dev Envを設定 with the devfile.yaml してよりカスタマイズすることもできます.

より詳細には以下を参照してください:

プルリクエスト

レポジトリメンテナーは次の流れであなたのPRを扱います.

我々がPRのレビュー時間を取れないからと言って、終わりではありません。20以上の支持があるissueはP2からP1へと格上げされます.

Step 1: 作業対象を探す

もし特定の機能や修正がある場合は, backlog にissueがすでに存在しないか確認してください. もし無い場合は, 修正を開始する前に機能リクエストやバグレポートを出してください. すぐに優先度を決定します, (P1 or P2) かの優先度によってPRの扱いが変わります.

issueを上げる必要はありませんが、issueがない場合は自動的に優先度が P2 になります.

作業対象のissueを探している場合は backlog of
issues
を見て興味があるものを探してください. 初めてのコントリビュートを探しているのであれば
'good first issue' label を見てみると良いです.

issueを探すときは常に優先度を意識してください. P2 はコミュニティの支持が集まるのを待っている段階で, すぐに取り掛かるものではありません. 複雑な実装の P2 issue はメンテナーによって閉じられることもあります. 多くのユーザにインパクトが有る P1 issueに集中したいのです.

Step 2: 設計

設計書の更新を繰り返してフィードバックを得ることが役立つ場合があります. 大きな変更や機能のアドバイスを求めている場合などです.

多くの場合、GitHubのissueのコメントは議論に十分ですが, 他にも以下のような選択肢があります.

  1. README駆動開発 - 新しいAPIをレビューする時に好まれるやり方です. 変更する機能の利用方法を説明したREADMEを更新したPRのドラフトを出します. 新しいL2コンストラクトの場合は一般的なユースケース例を網羅し、設計中のAPIの機能紹介を含めてください. 最も大事なのは公開APIで、これを見ればユーザが期待できる変更点を明らかにできます.
  2. RFCを書こう - 大きな範囲の機能を開発する場合, 破壊的な変更がある場合, コミュリティやコアチームとの詳細な議論が必要な場合 等に実施します. 特にCDKのコードベースと切り離すことができない新しい機能やCLIについて議論するのに適しています.
  3. パッケージの公開 - 分割されたパッケージは, CDKコアライブラリに含まれるべきだと信じている新機能の価値を示すのに最適です. APIの全景を示すだけではなく、実際に動作することを証明できます. aws-cdk-libに含まれる必要があるパッケージの場合は design guidelines を遵守してください.

上記を実施することでコントリビュートがなされる前に期待値を明確にすることができます. 我々は誰もがコントリビュートを効果的に貢献できるようにすることを望んでいます. もし aws-cdk-lib にマージされないPRがあった場合に, マージされるべきだと信じている場合は, それを追求することを推奨します. 長期間にわたり確実で高品質な保ち, 効果的にインタフェースを維持できるようにコアフレームワークの範囲は意図的に制限されています. しかしながら、現在のaws-cdk-libの仕組みよりも確実に優れたパターンが登場する場合もあります. あなたの解決方法がコミュニティで指示を集め, aws-cdk-libに含めることを再評価したい場合は cdk.dev で我々にアクセスするか GitHub issue で あなたのパッケージを参照する形で機能リクエストを出してください. 詳しくは demonstrating value を見てください.

Step 3: 魔法をかける

PRを出す前に実施することがあります.
以下のガイドラインに従いましょう:

  • コードスタイル.
    • 新しいコンストラクトを導入する場合, design guidelines を見てください.
      example construct library シンプルな単一コンストラクタの例一覧があります.
    • ビルドの間に適応される複数のlinterを使いコードの一貫性と正しさを保っています. エラーメッセージを確認し、対応してください.
  • 全ての変更は単体テストを必要とします
  • APIを変更した場合はモジュールのREADMEファイルを更新すること
    • モジュールのREADMEファイルを更新した場合もコンパイルが通ることを確認する必要があります. もし通らないとビルドエラーになります. コンパイル方法については Documentation を見てください.
  • プルリクエスト一つが対応する機能やバグ修正は一つに維持してください.多少のリファクタリングは問題ありません. 最終的には一つのコミットにまとめられるのでそれを参考にスコープを定めてください.

統合テスト

統合テストはCDKコードベースで新しい機能を実行します.

  1. デグレを検出するテストとして動作します. cdk synth を実行し *.snapshot ディレクトリと比較することでデグレを検出します.
  2. スタックから有効なクラウドフォーメーションテンプレートが出力されるか確認することで想定外の変更を防ぎます. yarn integ で実行でき, パッケージ内の全ての統合テストで cdk deploy を実行します. 統合テストを追加していたり、別の理由でいくつかのテストを何度も繰り返したい場合は yarn integ integ.test-name.js を使うこともできます. その場合は AWS credentials を設定するの忘れないでください.
  3. (オプション) クラウドフォーメーションのリソースがコンストラクトで期待通りに作られるか検証する動作もします. クラウドフォーメーションのデプロイが成功したことは、リソースが正しい状態であることを意味するわけではありません.

フレームワーク統合をビルドする

yarn integ を実行する前に framework-integ を実行する必要があります.

$ npx lerna run build --scope=@aws-cdk-testing/framework-integ

統合テストはいつ必要なのか?

以下のリストは統合テストが必要となる一般的なシナリオですが, 網羅的なリストではありません. ただし、これは網羅的なリストではありません。統合テストが不要となる正当な理由がない限り、すべての新機能とすべての修正に対してデフォルトで統合テストを実施します

  1. 新機能の追加
  2. 既存機能への修正の追加
  3. サービス全体にわたるリソース設定を含む場合
  4. 新しいサポートバージョンの追加 (e.g. a new AuroraMysqlEngineVersion)
  5. Custom Resource を使った機能追加

今後全ての統合テストは IntegTestコンストラクト を使う必要があります. 今後、既存のテストはこのコンストラクタを使うように更新していく予定で、これにより、各テストの設定をより細かく制御できるだけでなく、デプロイ済みのインフラストラクチャに対してアサーションを実行できるようになります.

/*
 * Stack verification steps:
 * * <step-1>
 * * <step-2>
 */

Examples:

統合テストを実施できない場合

統合テストを実施する必要があるPRに取り組んでいるが、cdk-integ を使った実際のデプロイを実行できない場合はプルリクエストでその旨お知らせください。メンテンナーが変わりにテストを実行します. --dry-run オプションを使って cdk-integ を実行したり、スナップショットを手動で更新したりしないでください.

CDK 統合テストを実行する完全な手順は integration test guide for a more complete guide on running
CDK integration tests.

yarn watch (Option)

yarn watch で コード変更時に自動ビルドすることができます.
例えば, aws-cdk-lib と aws-cdk モジュールを別のターミナルで実行するとwatchできます:

$ cd packages/aws-cdk-lib
$ yarn watch & # runs in the background
$ cd packages/aws-cdk
$ yarn watch & # runs in the background

デプロイして修正を確認する

PRがライブラリを更新する場合、シンプルなCDKアプリを作成し、クラウドフォーメーションテンプレートの生成とdeployが正しいことを確認したいでしょう. 例えば、packages/aws-cdk-lib/aws-eks のファイルを更新したら, シンプルなCDKアプリを作って動作を確認できます:

$ cd packages/@aws-cdk-testing/framework-integ/test/aws-eks/test

以下のような sample.ts を作ります:

import {
  App, Stack,
  aws_eks as eks,
  aws_ec2 as ec2,
} from 'aws-cdk-lib';
import { getClusterVersionConfig } from './integ-tests-kubernetes-version';

const app = new App();
const env = { region: process.env.CDK_DEFAULT_REGION, account: process.env.CDK_DEFAULT_ACCOUNT };
const stack = new Stack(app, 'my-test-stack', { env });

const cluster = new eks.Cluster(stack, 'Cluster', {
  vpc,
  ...getClusterVersionConfig(stack),
  defaultCapacity: 0,
});

sample.tssample.js にコンパイルするために yarn watch あるいは npx tsc --watch を実行します:

$ cd packages/@aws-cdk-testing/framework-integ
$ yarn watch
or
$ npx tsc --watch

デプロイして動作確認するため AWS CLI with AWS Authentication で設定する事を確認してください.

サンプルをデプロイします:

$ cd packages/@aws-cdk-testing/framework-integ
$ npx cdk -a test/aws-eks/test/sample.js diff
$ npx cdk -a test/aws-eks/test/sample.js deploy

これによりデプロイが期待通りであることを確認でき、開発を繰り返すことができるようになります.
一般のCDKアプリと同じように npx cdk diff で差分を確認することができますし npx cdk deploy -c でコンテキスト変数を渡すこともできます. 既存のVPCをインポートするなどして反復的なデプロイをしてテストを迅速に繰り返すことができます.

const vpc = ec2.Vpc.fromLookup(stack, 'Vpc', { isDefault: true });

sample.tssample.js はテスト専用なのでPRブランチに含めないでください.

あるいは, integ.my-test.ts のように新しい統合テストとして実装することもできます. yarn integ --no-clean でデプロイできます. 新しい統合テストをデプロイしたい時に便利です.

$ cd packages/@aws-cdk-testing/framework-integ
$ yarn integ test/aws-eks/test/integ.my-test.js --no-clean --update-on-failed

シンプルなデプロイで確認をしたら既存の単体テストと統合テストが通ることを確認する必要があります.

特定のモジュールの全ての単体テストを実行できます. (e.g. aws-eks):

$ cd packages/aws-cdk-lib
$ yarn test aws-eks

あるいは特定の単体テストを実行します.

$ cd packages/aws-cdk-lib
$ npx jest aws-eks/test/name.test.js

特定のモジュールの統合テストを全て実行します. (e.g. aws-eks):

$ cd packages/@aws-cdk-testing/framework-integ
$ yarn integ --directory test/aws-eks/test

あるいは特定の統合テストのみを実行します:

$ yarn integ test/aws-eks/test/integ.name.js

CDK統合テストを実行する完全なガイドは integration test guide を参照してください.

Step 4: プルリクエスト

  • fork からCDKリポジトリのクローンを作ってください.

  • ブランチを作成しコミット、プッシュしてください.

    [!IMPORTANT]
    プルリクエストは個人アカウントのブランチである必要があります (組織アカウントでもなく main ブランチでもない).
    CDKチームがあなたのブランチに変更をプッシュする 設定を有効にしておく必要があります.(これは個人アカウントのデフォルトで、組織アカウントでは有効化できません).
    これは、approve後にあなたのブランチを我々のmainに動悸する必要があるためです.

  • Githubでプルリクエストを作ります.

  • プルリクエストのタイトル、メッセージ、説明 コミット慣例 に従う必要があります.

    • タイトルは feat(module): title, fix(module): title, refactor(module): title, chore(module): title で始まる必要があります.
      • feat: 機能が更新されたことを示します (原則としてテストとREADMEの更新が必要ですが、抑制することもできます)
      • fix: バグ修正がされたことを示します (原則としてテストの更新が必要ですが、抑制することもできます)
      • docs: ドキュメントが更新されたことを示します (docstrings or Markdown files)
      • refactor: 機能が維持されたリファクタリングであることを示します
      • chore: ユーザにとってメリットのない変更で, CHANGELOGにきさいされません. build scripts, config, あるいはCHANGELOGに変更する必要がないほど小さな変更です.
    • feat and fix のPRのタイトルは変更履歴に残ります. ユーザにとって意味のある内容となるようによく考えてください.
      • feat: 機能について説明をしてください (「追加した」「変更した」等のPRの作業は避けてください)
      • fix: バグについて記載してください (解決策について記載しないでください)
    • タイトルは必ず小文字にしてください.
    • タイトルの最後のピリオドは不要です.
  • プルリクエストには 動機 を含める必要があります. コードレビューあの事を考え, 理解に必要な情報を記載しましょう. もし大きなコミットであれば、理解しやすいようにいくつかのエントリーポイントを準備しましょう.

    • バグの場合は, バグの内容, 根本原因, 解決策, 検討したが却下したその他の解決策を記載します.
    • 機能の場合, ユースケース, 最も重要な設計ポイント, (今回は選択しなかった)その他の設計案を記載します.
  • プルリクエストのメッセージはどのissueが修正されたかの情報を保つ必要がある. fixes #<issue> あるいは closes #<issue> が必要.

  • 協力者に声をかけます.

  • PRの一部として作成された 実行時依存関係 を記載します.

  • (ユニットテストなどによって), 動作確認が明らかな状態ではない場合は検証方法を説明してください.

  • 破壊的な変更を含む場合は --- の前に次のフォーマットで最後に記載する必要があります. さもないとCHANGELOGに記載されません.

    BREAKING CHANGE: Description of what broke and how to achieve this behavior now
    * **module-name:** Another breaking change
    * **module-name:** Yet another breaking change
    
    ---
    
    *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
    
    ---
    

    破壊的な変更は実験的なライブラリでのみ許されます. 実験的なライブラリは -alpha サフィックスがつきます. package.jsonstabilityexperimental を設定します .

  • プルリクエストが出されるとめいんてなーによってレビューアが設定されます.

  • プルリクエストのビルドが失敗す場合は、成功するまで修正を繰り返してください. ビルドが通らないまま4週間放置されるとそのプルリクS波自動で閉じられます.

  • レビューコメントについて議論し、少なくとも1つの「承認」が得られるまで繰り返し作業を進めます. 繰り返し作業中は、新しいコミットを同じブランチにプッシュします. 通常、これらのコミットはメインブランチにマージする際に一つのコミットにsquashされます. コミットメッセージは、マージコミットメッセージを確定する際のヒントとなるはずです.

  • 状況に変更があった場合は、必ずPRのタイトルと説明を更新してください。PRのタイトルと説明はコミットのタイトルとメッセージとして使用され、CHANGELOGにも表示されますので、プロセス全体を通して常に更新してください.

メンテナーからレビューをもらう

プルリクエストは山程届き、これは素晴らしいことです! どのプルリクエストをレビューすべきか優先順位を決めるために、まずプルリクエストがマージ可能な状態であることを確認します. つまり、プルリクエストは以下の条件を満たしている必要があります

  1. ドラフトではなくレビューの準備が整っている
  2. マージコンフリクトがない
  3. ビルドが通っている
  4. メンテナーからの変更依頼がない
  5. PR Linter ワークフローが通っているか あるいは コントリビュータが麺書を申請している.

これを簡単にするためプルリクエストに追加できる pr/needs-review というラベルがあります. PRにこのラベルがない場合は、何かプリリクエストに修正が必要であることを示しています.

[!NOTE]
リポジトリaws-cdkは頻繁に更新されるため、PRブランチがすぐに古くなり、「このブランチはベースブランチに対して古くなっています」というメッセージが表示されることがあります. ただし、新しくマージされたコミットとの競合がない限り、これは問題ではありません. PRが承認されると、自動化によって最新のmainブランチに更新され、マージが処理されます.

コンストラクトのランタイム依存の追加

CDK の一部ではなく、デプロイメントまたは実行時にコンストラクトで使用する必要があるツールは、次の 2 つの方法のいずれかで CDK フレームワーク ライブラリに含めることができます。

  1. ツールを含むnpmパッケージの直接の依存関係を追加します, @aws-cdk/asset-awscli-v1 等です.
  2. 作成中のコンストラクトにプロパティを公開し、ユーザーがツールの独自のバージョンを指定できるようにします。例えば、eks.Cluster コンストラクトには kubectlLayer というコンストラクトプロパティがあり、 @aws-cdk/asset-kubectl-vXY パッケージの1つから kubectl のバージョンを指定する必要があります。 kubectl のバージョンは、クラスターのKubernetesバージョンと互換性がある必要があります.

双方の選択肢も分離したレポジトリ (例えば kubectlの one に当たるもの) を作成する必要があります. 追加のランタイム依存を追加したい場合は、CDKのメンテナーと議論をして 依存関係をlambda layerとして提供するレポジトリをcdklabsに公開する必要があるでしょう. 通常、リポジトリの各ブランチは、依存関係の特定のバージョンに焦点を当てます。例えば、 awscdk-asset-kubectl の kubectl-v20/mainは ブランチではkubectl v1.20 を、kubectl-v21/mainkubectl では v1.21 をそれぞれ提供し、というように続きます.

PR によってラムダ レイヤーにランタイム依存関係が導入される場合は、その依存関係を管理する最適な方法について議論できるように、説明でそのことを必ず明記してください。.

新しい非伝統的な依存関係の追加

[!WARNING]
追加しないでください. CDKコンストラクトで使いたいツールがある場合, Adding construct runtime
dependencies
を見てください.

aws-cdk の場合、非標準的な依存関係は、モジュールの package.jsonファイルを介して管理されない依存関係として定義されます.

場合によっては、コンストラクトによって新しい非標準的な依存関係が構築されることがあります。導入された新しい非標準的な依存関係には、自動アップグレードプロセスが必要です。依存関係の更新には、 dependabotを使用することをお勧めします。dependabot の設定ファイルは、こちら から入手できます。

PR によって新しい非標準的な依存関係が導入されると思われる場合は、その依存関係を管理する最善の方法を議論できるように、説明でそのことを必ず明記してください.

コードカバレッジギャップの解決

プロジェクトのコードカバレッジを追跡するために Codecov を活用しています。PRがカバレッジ要件を満たしていない場合、ステータスチェックに失敗が表示され、PRのマージが妨げられます。

私たちが定義する要件は 2 つあり、それぞれがプロジェクト全体と個々のパッケージの両方に適用されます。

カバレッジ率は減少してはなりません。
パッチの割合は少なくとも 95% である必要があります。
以下は、両方の要件に違反する PR のステータス チェックの例です。

PR 内のカバレッジ ギャップを修正および診断するには、次の 2 つのオプションがあります。

  1. 変更を PR にプッシュし、Codecov が PR にコメントするのを待ちます。
  2. オプション1が遅すぎる場合は、次の場所にあるローカルカバレッジレポートを開いてください。<path-to-package>/coverage/index.html

[!NOTE]
ローカルレポートのカバレッジ率は、Codecov に表示されるカバレッジ率と若干異なります。これは問題ありません。Codecov が関数シグネチャを処理する方法に関係していると思われます。最終的には Codecov が信頼できる情報源ですが、ローカルレポートを使用してカバレッジされていない行を特定し、対処することも可能です.

稀ではありますが、特定の行をテストでカバーするのが難しい場合があります。特定の行のカバレッジを無効にするには、次のコマンドを使用します。

/* istanbul ignore next */
console.log('This cannot be covered')

Step 5: マージ

  • PR が正常にビルドされたことを確認します (すべての PR を自動的にビルドするように CodeBuild が設定されています)。
  • 承認されテストされると、当社のボットの 1 つがメインにスカッシュマージし、PR のタイトル/説明をコミット メッセージとして使用します。

[!NOTE]
プルリクエストが必須チェック(例:Codecov)のいずれかに不合格の場合、自動マージは行われません。それでもプルリクエストをマージすべきだと思われる場合は、メンテナーにお知らせください。メンテナーは同意してプルリクエストを手動でマージするか、不合格のチェックへの対処を依頼する場合があります。

破壊的な変更

NOTE: AWS CDK バージョン 2.0.0 以降、**メイン CDK ライブラリ一部として提供されるすべてのモジュールとメンバー aws-cdk-lib ** は常に安定しています. メジャーバージョン以外の変更では互換性を破る変更を導入しないことを約束しています。互換性を破る変更は、プレリリース (実験的または開発プレビュー) モジュール (それぞれのpackage.json ファイルの stabilityexperimental のもの) でのみ許可されます。v1ではそれぞれのモジュールは別々にリリースされます. v2では stable のみが main の一部としてリリースされます. experimental-alpha として独立してリリースされ、mainのCDK libraryには含まれません.

変更を加える際には、その変更によって ライブラリの既存ユーザーに支障が生じる可能性があります。お客様が現在のバージョンのCDKで作成していたプログラムが、提案された新しいバージョンのCDKでは「正しく動作」しなくなる場合、その変更は支障をきたすものとなります。

安定版ライブラリでは、互換性を損なう変更は許可されません。実験的なライブラリでは、モジュールのメンテナーが回避すべきと判断しない限り、互換性を損なう変更は許可されます。互換性を損なう変更は、プルリクエストの本文で明示的に記述する必要があります.

破壊的な変更には以下の2種類があります:

  • APIのIFの変更
  • 振る舞いの変更

API IFの変更

これには、APIの形状に影響を与えるあらゆる変更が含まれます。既存のプログラムのコンパイルに失敗するような変更は許可されません。典型的な例を以下に示します:

  • クラスまたはメソッドの名前を変更する
  • コンストラクタまたはメソッドへの入力として使用される構造体に、必須のプロパティを追加します。これには、型をnull許容型からnull非許容型に変更することも含まれます。
  • メソッドから返される構造体からプロパティを削除する、またはクラスからプロパティを削除します。これには、型をnull非許容からnull許容に変更することも含まれます。

後者がなぜ問題になるのかを確認するには、次のクラスを考えてみましょう。

class SomeClass {
  public readonly count: number;
  //               ❓ 'count?: number' に変えたいと考えてみましょう
  //                  つまりオプショナルにしたい
}

// 誰かが以下のようなコードを書くかもしれません:
const obj = new SomeClass();
console.log(obj.count + 1);

// 提案の変更をした後今まで成功していたコンパイルに失敗します
console.log(obj.count + 1);
//          ~~~~~~~~~ Error: Object is possibly 'undefined'.

CDKには、変更によってAPIサーフェスに重大な変更が生じていないかどうかを確認するためのビルドツールが付属しています。パッケージディレクトリで以下を実行してください:

$ yarn build
$ yarn compat

公開APIを無効化することが正当な唯一のケースは、既存のAPIにバグがあり、それが機能の使用を妨げている場合です。つまり、このAPIを無効化しても、誰もそのAPIを使えなくなるため、誰も影響を受けることはありません。 allowed-breaking-changes.txt リポジトリのルートにあるファイルは、このような場合に使用できる除外ファイルです。

破壊的なAPIサーフェスの変更への対処

一部の API 要素のタイプを変更する必要がある場合は、新しい API 要素を導入し、古い API 要素を @deprecated としてマークします。

API を実装する目的で値があるかのように見せかける必要があるが、実際に返す有用な値がない場合は、プロパティ getter を作り例外をスローしても問題ありません (コンストラクトのユーザーに役立つエラー メッセージを記述することを念頭に置いてください):

class SomeClass implements ICountable {
  constructor(private readonly _count?: number) {
  }

  public get count(): number {
    if (this._count === undefined) {
      // ✅ DO: ユーザに何をしているか提示できる説明的なエラーを返す
      throw new Error('This operation requires that a \'count\' is specified when SomeClass is created.');
      // ❌ DO NOT: 'count is missing' のようにただエラーを返すのではだめです
    }
    return this._count;
  }
}

振る舞いの変更

これらの変更は、以前のAPIを使用して作成されたプログラムのコンパイルには直接影響しませんが、意味が変わる可能性があります。実際には、ユーザーがコードを変更していなくても、合成されるCloudFormationテンプレートは異なります。

テンプレートの変更がすべて破壊的変更になるわけではありません。以前のバージョンのライブラリを使用してスタックを作成し、CDKライブラリのバージョンを更新し、現在アップデートをデプロイしているユーザーを考えてみましょう。以下の場合、動作の変更は破壊的変更となります:

  • アップデートがまったく適用できない
  • 更新は適用できますが、サービスが中断したり、データが失われたりする可能性があります

データ損失は、 ステートフルリソースの論理ID
ID
が変更された場合、または置換が必要なリソースプロパティのいずれか が変更された場合に発生します。どちらの場合も、CloudFormation はリソースを削除し、データベースなどのステートフルリソースの場合は、そのリソース内のデータも失われます。

変更が問題なく適用され、サービスの中断を引き起こさない場合は、破壊的な変更とはみなされません。しかしながら、ユーザーは予期せぬテンプレートの変更に当然ながら警戒し、綿密に精査するため、このような変更は避けるのが賢明かもしれません。ユーザーベースに不必要なパニックや離脱を引き起こしたくないからです。

動作の変更が破壊的であるかどうかを判断するには、ライブラリ所有者の専門知識と判断力、およびテストが必要です.

破壊的なふるまいの変更に対応する

ほとんどの場合、動作の変更は、何らかのプロパティのデフォルト値またはデフォルトの動作を変更する必要があるために発生します (つまり、値が欠落している場合の意味の解釈を変更する必要がある).

新しい動作が破壊的なものになる場合、ユーザーは次のいずれかの方法でそれを使用するかどうか選択する必要があります:

  • 新しい API 要素 (クラス、プロパティ、メソッドなど) を追加して、ユーザーがソース コード レベルで新しい動作を明示的に選択できるようにする ( 一緒に@deprecateな古い API 要素を変更する可能性もあります)。

  • 機能フラグメカニズムを使用すると、ソース コードを変更せずにユーザーが新しい動作を選択できるようになります。

これら 2 つのうち、可能であれば最初のものが優先されます (機能フラグには非ローカル効果があり、意図しない効果を引き起こす可能性があるため)。

新しい実験的な(「プレビュー」)APIの追加

互換性を損なう変更をリリースしないというコミットメントを維持しながら、機能を迅速に追加し続けることができるように、API プレビューという新しいモデルを導入します。開発者に早期に提供したい、まだ確定していない API は、特定のサフィックス が付いて AWS CDK に追加されます。BetaXプレビュー サフィックスが付いた API は削除されることはありません。代わりに、廃止され、安定バージョン (サフィックスなし) または新しいプレビュー バージョンに置き換えられます。たとえば、grantAwesomePowerBeta1 メソッド を追加するとします 。

/**
 * このメソッドはすげーことすんぞ
 */
grantAwesomePowerBeta1();

時が経つにつれ、このメソッドは実際には Principal を引数として受け入れる方がはるかに良いというフィードバックをいただくようになりました. 必須プロパティの追加は互換性を破る変更であるため、grantAwesomePowerBeta2 を追加し、grantAwesomePowerBeta1 を非推奨にします:

/**
* This method grants awesome powers to the given principal
*
* @param grantee The principal to grant powers to
*/
grantAwesomePowerBeta2(grantee: iam.IGrantable)

/**
* This method grants awesome powers
* @deprecated use grantAwesomePowerBeta2
*/
grantAwesomePowerBeta1()

API を卒業する時期が来たと判断されると、最新のプレビュー バージョンは廃止され、最終バージョンのgrantAwesomePowerが追加されます.

新しい実験的なCLI機能の追加

新しい CLI 機能を迅速に開発するために、機能を「試験的」または「段階的」にリリースする場合があります。このシナリオでは、--unstable フラグによる明示的なオプトインを利用できます--unstable。

明示的なオプトインとは以下のような感じです:

cdk new-command --unstable='new-command'

cdk bootstrap --unstable='new-funky-bootstrap'

作業中のCLIコマンドにフラグとして追加するだけで済みます。コマンドが安定する時期が来たら、このようなフラグの設定は必須ではなくなります.

ドキュメント

各モジュールのREADMEは、公式ドキュメントのランディングページとして表示されます。例えば、このaws-ec2モジュールのREADMEは次のようになります - https://docs.aws.amazon.com/cdk/api/latest/docs/aws-ec2-readme.html。

ロゼッタ

READMEファイルには、TypeScriptコードとして記述されたコードスニペットが含まれています。コードブロック内に入力されたコードスニペットは、自動的に抽出、コンパイルされ、他の言語に翻訳されます。この機能は「Rosetta」と呼ばれています。

次のコマンドを実行すると、aws-cdk-lib モジュール (またはその他のモジュール) で rosetta を実行できます。

$ cd packages/aws-cdk-lib
$ yarn rosetta:extract --strict

これを成功させるには、コンパイル可能でなければなりません。最も簡単な方法は、次の例のようなフィクスチャを使用することです。

```ts fixture=with-bucket
bucket.addLifecycleTransition({ ...props });
```

上記例の処理中にツールは rosetta/with-bucket.ts-fixture という名前のファイルをパッケージから探します.
このファイルは通常のTypeScriptソースファイルとして扱われますが、/// here というテキストも含まれている必要があり、ここに例文が挿入されます。ファイル全体は正常にコンパイルされる必要があります。

/// here の前に, フィクスチャは必要なパッケージをインポートし、必要な変数を初期化する必要があります。

フィクスチャが指定されていない場合は、rosetta/default.ts-fixtureが使用されます(存在する場合)。nofixture を使用して、その動作をオプトアウトできます。

@example ブロックでコードブロック医囲まれていない場合、@exampleMetadata タグで例に関連する追加情報を提供できます。

/**
 * @exampleMetadata fixture=with-bucket
 * @example
 *   /// fixture=with-bucket
 *   bucket.addLifecycleTransition({ ...props });
 */

サンプル コードをコンパイル可能にする方法の実際の例については、 aws-ec2パッケージを参照してください。

⚠️ NOTE: README ファイルには、現在のモジュールを利用するモジュールを参照するコードスニペットが含まれていることが多く、そのため現在のモジュールの依存関係クロージャには存在しません。参照されているモジュールがビルドされていない場合、これらのスニペットのコンパイルは失敗します。スニペットの操作を最適に行うには、CDK リポジトリのフルビルドが必要です。ただし、必要に応じてこれらのモジュールを「ビルド」することをお勧めします。

推奨事項

AWS CDK コードベース全体で一貫したドキュメント スタイルを提供するために、サンプル コードは次の推奨事項に従う必要があります (これらの推奨事項の一部が適用されない場合もあります。適切な判断が必要です):

  • ドキュメント化されたモジュールの方は 修飾されていない 必要があります:

    // aws-cdk-lib ライブラリで Duration を定義している例
    Duration.minutes(15);
    
  • 他のモジュールの型は修飾されている必要があります:

    // aws-cdk-lib library aws-cdk-lib/aws-s3 を使用している例
    const bucket = new s3.Bucket(this, 'Bucket');
    // ...rest of the example...
    
  • コンパイルには必要だが例では重要ではない値については、例の中で直接 declare ステートメントを使用します:

    // aws-cdk-lib/pipelines ライブラリのパイプラインにstageを追加する例
    declare const pipeline: pipelines.CodePipeline;
    declare const myStage: Stage;
    pipeline.addStage(myStage);
    

    コンパイルには必要だが例では重要ではない場合、新しいファイルを作るのではなく、既存の default.ts-fixture を利用します. これは、.ts-fixture ファイルに保存された値はドキュメントに表示される例には表示されないため、コンパイルの成功には役立ちますが、ユーザーが例を理解するのには役立ちません。

ツール(詳細)

スクリプト/foreach.sh

この素晴らしいツールは、リポジトリ内のすべてのモジュールに対してトポロジカルな順序でコマンドを実行できるだけでなく、ステートフル(状態を保持する)という驚くべき特性を備えています。つまり、コマンドが失敗した場合でも、問題を修正して中断したところから再開できるのです。

セッションを開始するには、次のコマンドを実行します。

$ scripts/foreach.sh COMMAND

リポジトリ内の各モジュールに対して「COMMAND」を実行します(cwdはモジュールのディレクトリです)。タスクが失敗した場合、タスクは停止します。再開するには、foreach.sh再度実行してください(同じコマンドの有無は問いません)。

セッションをリセットするには (すべてのタスクが完了したとき、または別のセッションを実行する場合)、次を実行します。

$ scripts/foreach.sh --reset

モジュールの依存関係のクローズに対してのみコマンドを実行する場合は、次を使用します。

$ cd packages/my-module
$ ../scripts/foreach.sh --up COMMAND

これは、my-moduleに関するすべての依存関係に対してCOMMANDを実行します。
その結果 foreach.sh の上に構築されたモジュールを構築できるスクリプトがあります.

  • scripts/buildup: 現在のモジュールとそのすべての依存関係を(トポロジカルな順序で)構築します。
  • scripts/builddown: 現在のモジュールとそのすべてのコンシューマーを(トポロジカルな順序で)構築します。

リンター

すべてのリンターはビルド スクリプト yarn build の一部として自動的に実行されますyarn build。
ビルドスクリプトとは独立して実行することもできます。特定のパッケージ(例 packages/aws-cdk-lib)のルートから次のコマンドを実行すると、そのパッケージのすべてのリンターが実行されます。

yarn lint

以下のリンターが使用されます。

ESLint

リポジトリ内のすべてのパッケージは、eslintrc.js にある標準の基本設定を使用します。この設定は、ルートにある .eslintrc ファイルを変更することで、任意のパッケージに合わせてカスタマイズできます。

VS Code を使用しており、ESLint 違反を確認したい場合は、ESLint
extension
をインストールしてください。

pkglint

pkglint ツールは、rules.tsに従ってリポジトリ全体の package.json ファイルを「lint」します。

リポジトリ内のすべてのパッケージ リンティングの問題を評価 (および修正) するには、リポジトリのルートから (ブートストラップ後に) 次のコマンドを実行します。

$ lerna run pkglint

パッケージごとにこれを行うこともできます。

$ lr pkglint

awslint

awslint は、AWS Construct Library API 用のリンターです。プロジェクト内のすべての AWS モジュールのビルドの一部として実行され、AWS Construct Library Design Guidelines 設計ガイドラインに準拠します。

詳細の情報は awslint README を参照ください.

一般的に、awslint のルールに違反する変更を行った場合、ビルドは失敗し、適切なメッセージが表示されます。すべてのルールはガイドラインに記載され、説明されています。

以下に、役立つコマンドをいくつか示します。

  • yarn awslint すべてのモジュールで、そのモジュールに対して awslint が実行されます。
  • yarn awslint list すべてのルールを出力します (詳細と根拠はガイドライン ドキュメントに記載されています)。
  • scripts/foreach.sh yarn awslint リポジトリ全体のlintを段階的に開始します。scripts/foreach.sh 修正後に再実行して続行してください。
  • lerna run awslint --no-bail --stream 2> awslint.txt すべてのモジュールで awslint を実行し、すべての結果をawslint.txtに収集します。
  • lerna run awslint -- -i <RULE> リポジトリ全体で awslint を実行し、指定されたルールのみを評価します 。包含/除外ルール パターンの詳細については、awslint README を参照してください。

JetBrains のサポート (WebStorm/IntelliJ)

このプロジェクトはlernaを使用し、ネストされた node_modules ディレクトリ内のシンボリックリンクを利用しています。インデックス作成中に問題が発生する場合があります。IDEがこれらのディレクトリのインデックス作成を試み、リンクをたどり続けるため、メモリ不足でプロセスがクラッシュすることがあります。この問題を解決するには、これらのディレクトリを除外するコマンド node ./scripts/jetbrains-remove-node-modules.js を実行してください。

このリポジトリへのリンク

独自の CDK アプリケーションまたはライブラリを開発していて、npm のバージョンではなく、ローカルにチェックアウトされた AWS CDK のバージョンを使用する場合は、この ./link-all.sh スクリプトが役立ちます。

このスクリプトは、ローカルの AWS CDK リポジトリでビルドされたモジュールを、CDK アプリまたはライブラリの node_modules/ フォルダの下にシンボリックリンクします。

$ cd <your own CDK app>
$ <path to the AWS CDK repo>/link-all.sh

統合テストを並行して実行する

統合テストガイド を参照してください

CloudFormation テンプレートの依存関係を視覚化する

template-deps-to-dot でGraphbizを使います.

$ cdk -a some.app.js synth | $awscdk/scripts/template-deps-to-dot | dot -Tpng > deps.png

パッケージ間の依存関係の循環を見つける

find-cycles で内部の依存関係の循環のリストを出力できます.

CLI統合テストの実行

CLIパッケージ(packages/aws-cdk)には、特別な要件があるため、通常のビルドでは実行されない統合テストがいくつかあります。これらのテストの実行方法の詳細については、CLI CONTRIBUTING.mdファイルを参照してください。

v2 -alpha パッケージの構築とテスト

安定していないモジュールは aws-cdk-lib とは別に提供されます。これらのパッケージは packages/@aws-cdk ディレクトリにあり 、package.json ファイルでstability: 'experimental'のマークされています。つまり、version.v2.json によって公開時にalphaのバージョンが付与され、 aws-cdk-lib によって依存関係として取得されることはありません。

試験的パッケージは、新しいコンストラクトを開発し、試し、安定版として aws-cdk-lib に含める前に使用されます. aws-cdk-lib に組み込むとaws-cdk-lib、APIに破壊的変更を加えることはできなくなります。

アルファ パッケージ (たとえば、some-package-alpha) をビルドする場合、リポジトリのルートで次のコマンドを実行して、アルファ パッケージとその依存関係をビルドできます。

$ npx lerna run build --scope=@aws-cdk/some-package-alpha

この時点で、アルファ パッケージのビルドとテストを実行できます。

$ cd packages/@aws-cdk/some-package-alpha
$ yarn build
$ yarn test

Cloud Assembly スキーマの変更

cloud-assembly-schema パッケージに変更を加える予定がある場合は、必ずパッケージのコントリビュートガイドをよく読んでください。

機能フラグ

CDKのデフォルトの動作として正しいと確信しているため、新しい互換性のない動作を導入したい場合があります。しかし、当然ながら問題は、互換性のない変更はメジャーバージョンでのみ許可されており、しかもその頻度は稀であるということです。

このニーズに対応するため、機能フラグのパターン/メカニズムを用意しました。これにより、新しい互換性を損なう動作を導入できます。この動作はデフォルトでは無効になっています(既存のプロジェクトには影響しません)。ただし、cdk init を通じて作成された新しいプロジェクトでは自動的に有効になります。既存のユーザーは、自分のスケジュールに合わせて新しい動作を選択的にオプトインできます。

変更によって CloudFormation テンプレートに違いが生じ、更新中に次のいずれかが発生する場合は、新しい動作を自動的に適用するのは安全ではないため、機能フラグを使用する必要があります。

  • リソースの置き換えによりサービスが中断される、または
  • ユーザーは古い設定を前提としている可能性があり、変更によってそれが壊れる

新しいフラグを追加すると次のようになります。

  1. cx-api/lib/features.ts に新しい固定値であるキーを定義し、それによって機能を有効化する. 例えば ENABLE_STACK_NAME_DUPLICATES のようなイメージ. このキーは module.Type:feature の形式に従う必要があります.((e.g. @aws-cdk/core:enableStackNameDuplicates))

    • introducedIn.v2'V2NEXT' を設定します.
    • 2重否定は避けてください. 以前有効だったものを無効にするフラグを追加したいときは default.v2truerecommendedValuefalse にしてください. features.test.ts のテストを修正してください.
  2. FeatureFlags.of(construct).isEnabled(cxapi.ENABLE_XXX) を使って機能が有効かどうかチェックしてください. 定義されていない場合は従来の動作に戻します.

  3. cx-api/lib/features.tsFLAGS に機能フラグを追加します. 説明には必ず以下を含めてください.

    • 機能フラグの種類を慎重に選択してください。将来のメジャーバージョンでそのフラグを削除できるかどうかを検討してください。
    • 機能フラグが存在する理由を説明してください。既存のインフラストラクチャにどのような変更が加えられ、なぜ安全ではないのでしょうか。
    • 「デフォルト変更フラグ」の場合は、古い動作を復元するためにユーザーが行う必要がある操作を説明します。
  4. README ファイルに機能のエントリを追加します.

  5. テストでは、機能フラグを有効にした状態と有効にしていない状態で機能をテストしてください。これは、App をインスタンス化する際に、機能フラグを context プロパティに渡すことで実行できます。

    const myFeatureFlag = { [cxapi.MY_FEATURE_FLAG]: true };
    const app = new App({
       context: myFeatureFlag,
    }),
    const stackUnderTest = new Stack(app);
    
  6. PRのタイトル (CHANGELOGに残ります)には (under feature flag) サフィックスを追加してください. 以下のような例です.

    fix(core): impossible to use the same physical stack name for two stacks (under feature flag)

バージョン管理とリリース

CDK のバージョンがどのように維持され、新しいリリースをトリガーするかの詳細については、release.md を参照してください。

トラブルシューティング

ほとんどのビルドの問題は、完全なクリーンリビルドを実行することで解決できます。

$ git clean -fqdx .
$ yarn install
$ yarn build

ただし、これには時間がかかります。このセクションでは、発生する可能性のある一般的な問題と、問題を解決するために実行できる、より具体的なコマンドについて説明します。

名前を変更したファイルでコンパイラがエラーをスローしています/削除するつもりだった古いテストが実行されています/コード カバレッジが低く、何も変更していません。

.ts ファイルが名前変更または削除されたブランチに切り替えると、前回のコンパイル実行で生成されたファイル.js.d.tsファイルはそのまま残り、場合によってはコンパイラまたはテスト ランナーによって取得されることがあります。

古いビルド成果物をクリアするには、以下を実行します。

$ scripts/clean-stale-files.sh

依存関係を追加しましたが、ビルドで認識されません

Lerna にすべての依存関係を更新するように指示する必要があります。

$ node_modules/.bin/lerna bootstrap

依存関係を追加しましたが、watch バックグラウンド コンパイル実行でそれが取得されません。

いいえ、違います。再起動後、watchコマンドを再起動する必要があります。

依存関係を追加しましたが、Visual Studio Code によって認識されません (赤い下線が引き続き表示されます)。

実行中のTypeScriptコンパイラは依存関係ツリーをキャッシュしました。再ブートストラップ後、TypeScriptコンパイラを再起動してください。

F1を押下し, > TypeScript: Restart TS Server を入力します.

パッケージ間のリファクタリングを行っていますが、コンパイル時間が長すぎて困っています。また、異なるバージョンのブランチ間を頻繁に切り替える必要があり、バージョンエラーによる再構築に時間がかかりすぎています。

各パッケージのビルドステップでは、コードの生成やJSIIアセンブリの生成など、いくつかの処理が行われます。すべてのソースファイルを生成するためにフルビルドを少なくとも1回実行している場合は、以下の手順でソースツリー全体をTypeScriptのみで再構築することで、より迅速に作業を進めることができます。

# 少なくとも一度はフルビルドしてソースファイルを作っておく必要があります
$ scripts/build-typescript.sh

# プロジェクト横断の watch コンパイルでも同様に機能します
$ scripts/build-typescript.sh -w

この方法ではコード生成は行われず、JSIIチェックやJSIIアセンブリ生成も行われません。パッケージごとに順番にビルドするのではなく、リポジトリ内のすべての.tsファイルを一度にコンパイルします。これは、最大のパッケージを単独でコンパイルするのとほぼ同じ時間がかかります。私のマシンでは、15CPU分のビルドと20CPU秒のビルドの違いがあります。この再コンパイル方法を使用してテストを実行する場合は、組み込みのリビルド機能をlerna run test無効にする必要があります。

$ CDK_TEST_BUILD=false lr test

デバッグ

VS Codeデバッガーの接続

Note: これは TypeScript CDK アプリケーションにのみ適用されます。

CDKアプリケーションをCDKリポジトリとともにデバッグするには、

  1. CDKリポジトリをローカルにクローンし、リポジトリをビルドします。様々なビルドオプションについては、ワークフローセクションをご覧ください。

  2. 適切な npm スクリプト (通常は yarn build)を使用して CDK アプリケーションをビルドし、次のように link-all.sh スクリプトを実行します。

    cd /path/to/cdk/app
    /path/to/aws-cdk/link-all.sh
    
  3. CDK アプリケーション (hello-cdkとします) CDK リポジトリをVS コードのマルチルート ワークスペースとして開きます。

  4. ワークスペース設定ファイル を開き、次の2つのフォルダがすでに存在していることを確認します。

{
  "folders": [
    { "path": "<path-to-cdk-repo>/aws-cdk" },
    { "path": "<path-to-cdk-app>/hello-cdk" }
  ],
}
  1. 設定ファイルに次の起動構成を追加します
"launch": {
  "configurations": [{
    "type": "node",
    "request": "launch",
    "name": "Debug hello-cdk",
    "program": "${workspaceFolder:hello-cdk}/bin/hello-cdk.js",
    "cwd": "${workspaceFolder:hello-cdk}",
    "console": "internalConsole",
    "sourceMaps": true,
    "skipFiles": [ "<node_internals>/**/*" ],
    "outFiles": [
      "${workspaceFolder:aws-cdk}/**/*.js",
      "${workspaceFolder:hello-cdk}/**/*.js",
    ],
  }]
}

NOTE: 起動構成の詳細については、こちらをご覧ください。

  1. デバッグ ビューには、「Debug hello-cdk」という起動構成が含まれるようになり、これを起動するとデバッガーが起動します。
  2. CDKアプリまたはCDKモジュールを変更するたびに、それらを再構築する必要があり、変更内容によっては手順2のlink-all.shスクリプトを再実行する必要がある場合があります。そうすることで初めて、VS Codeは変更を認識し、場合によってはブレークポイントも認識します。

デバッガーでCDKユニットテストを実行する

CDK プロジェクト自体の単体テストで VSCode デバッガーを実行する場合は、次の手順を実行します。

  1. ユニット テスト内にブレークポイントを設定します。
  2. ターミナルで、テストの種類に応じて次のいずれかを実行します。
# (For tests names test.xxx.ts)
$ node --inspect-brk /path/to/aws-cdk/node_modules/.bin/nodeunit -t 'TESTNAME'

# (For tests names xxxx.test.ts)
$ node --inspect-brk /path/to/aws-cdk/node_modules/.bin/jest -i -t 'TESTNAME'
  1. VSCode の Run ペインで、実行構成 Attach to NodeJS を選択し、ボタンをクリックします。

バッジ(パイロットプログラム)

CDKメリットバッジはパイロットプログラムです。取得できるバッジは試験的なもので、変更される可能性があります。

CDKメリットバッジは、CDKコントリビューターのエクスペリエンス向上を目的としたプログラムです。CDKリポジトリに新しいプルリクエストを送信すると、リポジトリへの過去の成功したコントリビューション数を反映したメリットバッジが付与されます。現在、これらのバッジは単なる楽しみのためのものであり、CDKへの継続的なコントリビューションへのささやかなインセンティブとして提供されています。

バッジには次のような意味があります。

  • beginning-contributor: CDK に 0~2 件の PR を投稿しました
  • repeat-contributor: CDK に 3~5 件の PR を投稿しました
  • valued-contributor: CDKに6~12件のPRを投稿しました
  • admired-contributor: CDKに13~24件のPRを投稿しました
  • star-contributor: CDKに25~49件のPRを投稿しました
  • distinguished-contributor: CDKに50以上のPRを寄稿しました

関連リポジト

  • Samples: 複数の言語のサンプルコードが含まれています
  • Workshop: https://cdkworkshop.com のソース
  • Developer Guide: 開発者ガイドのマークダウンソース
  • jsii: 多言​​語サポートに使用しているテクノロジーです。新しい言語のサポートにご協力いただける場合は、まずはjsiiから始めてください。

以上!長かった!

Discussion