diff --git a/.dockerignore b/.dockerignore index cbc509d..7a5676a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,3 @@ -docker_test.sh README.md .gitignore CODEOWNERS @@ -10,4 +9,5 @@ LICENSE src/__tests__/* copilot/* Dockerfile -docker-compose.yml +compose.yaml +run_local.sh diff --git a/.github/workflows/react-jest.yaml b/.github/workflows/react-jest.yaml index 5ac81a5..6c61fa7 100644 --- a/.github/workflows/react-jest.yaml +++ b/.github/workflows/react-jest.yaml @@ -1,3 +1,4 @@ +# node_version: 20, 22とenvironment_type: development, staging, productionの計6パターンでテストを実行 name: run-jest on: push: @@ -22,6 +23,9 @@ jobs: strategy: matrix: node_version: [20, 22] + environment_type: ["development", "staging", "production"] + environment: + name: ${{ matrix.environment_type }} steps: # checkout repository to runner @@ -40,5 +44,29 @@ jobs: - name: install dependencies run: github-comment exec --token ${{ secrets.token }} -- npm install - - name: run npm test - run: github-comment exec --token ${{ secrets.token }} -- npm test -- --watchall=false + # 3環境まとめてテスト + - name: run npm run test + env: + GH_TOKEN: ${{ secrets.token }} # gh用 + run: | + if [ ${{ matrix.environment_type }} = "development" ]; then + npm_type="dev" + elif [ ${{ matrix.environment_type }} = "staging" ]; then + npm_type="stg" + elif [ ${{ matrix.environment_type }} = "production" ]; then + npm_type="prod" + else + echo "invalid environment_type" + exit 1 + fi + # environmentにあった名称でenv_fileを作成し,github actions environment variableを書き込み + # NOTE: env_fileはgitで管理したくないため,workflow実行時に作成している。 + env_file=".env.${{ matrix.environment_type }}" + touch $env_file + cat <> $env_file + $(gh variable list --env ${{ matrix.environment_type }} | awk '{print $1"="$2}') + EOF + echo ----[DEBUG]: CHECK $env_file---- + cat .env.${{ matrix.environment_type }} + echo ----[DEBUG]: END---- + github-comment exec --token ${{ secrets.token }} -- npm run test-$npm_type -- --watchall=false diff --git a/.gitignore b/.gitignore index 88c646a..061e554 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ .env.development .env.test.local .env.production +.env.staging npm-debug.log* yarn-debug.log* diff --git a/Dockerfile b/Dockerfile index c548447..a861e58 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,16 +10,19 @@ COPY . . # npm startは.env.developmentが優先されるがnpm run buildでは.env.productoinが優先されるので注意。 RUN < .env.${environment} +done +``` + +- github actions enrironment variablesに登録/更新する。 + +```shell +source ./update_github_actions_variables.sh +``` + +### GitHub Actionsで実行したスキャン結果をアップロードできるようにGitHubリポジトリの設定を変更する + +- GitHub Actionsがスキャン結果のファイルをアップロードできるようにGitHubリポジトリの設定を変更。詳細は[semgrepのyaml](./.github/workflows/react-semgrep.yaml)を参照。 + +--- ## HOW TO USE -- ローカルでのセットアップが必用なのは git-secretsのセットアップ。 +### コミット時の検査セットアップ + +- git-secretsのセットアップ。 ```shell cd devsecops-demo-aws-ecs @@ -90,14 +135,13 @@ pip install pre-commit pre-commit install ``` -- VSCodeのExtensionsもお好みでインストール。 -- GitHub Actionsがスキャン結果のファイルをアップロードできるように権限をつける。詳細は[semgrepのyaml](./.github/workflows/react-semgrep.yaml)を参照。 - --- ## ERROR LOG
-今まで詰まったエラー一覧
- -
+今まで詰まったエラー一覧 +
+TODO +
+ diff --git a/initialsettings_aws.md b/doc/archive/initialsettings_aws.md similarity index 100% rename from initialsettings_aws.md rename to doc/archive/initialsettings_aws.md diff --git a/doc/fig/actions-secrets-set.png b/doc/fig/actions-secrets-set.png new file mode 100644 index 0000000..56965c9 Binary files /dev/null and b/doc/fig/actions-secrets-set.png differ diff --git a/doc/fig/cfn/app-infrastructure-roles.png b/doc/fig/archive/cfn/app-infrastructure-roles.png similarity index 100% rename from doc/fig/cfn/app-infrastructure-roles.png rename to doc/fig/archive/cfn/app-infrastructure-roles.png diff --git a/doc/fig/cfn/app-infrastructure.png b/doc/fig/archive/cfn/app-infrastructure.png similarity index 100% rename from doc/fig/cfn/app-infrastructure.png rename to doc/fig/archive/cfn/app-infrastructure.png diff --git a/doc/fig/cfn/env.png b/doc/fig/archive/cfn/env.png similarity index 100% rename from doc/fig/cfn/env.png rename to doc/fig/archive/cfn/env.png diff --git a/doc/fig/cfn/pipeline.png b/doc/fig/archive/cfn/pipeline.png similarity index 100% rename from doc/fig/cfn/pipeline.png rename to doc/fig/archive/cfn/pipeline.png diff --git a/doc/fig/cfn/svc.png b/doc/fig/archive/cfn/svc.png similarity index 100% rename from doc/fig/cfn/svc.png rename to doc/fig/archive/cfn/svc.png diff --git a/doc/fig/github-environment.png b/doc/fig/github-environment.png new file mode 100644 index 0000000..e3ff21d Binary files /dev/null and b/doc/fig/github-environment.png differ diff --git a/doc/fig/pat.png b/doc/fig/pat.png new file mode 100644 index 0000000..23c33dd Binary files /dev/null and b/doc/fig/pat.png differ diff --git a/doc/github-actions.md b/doc/github-actions.md index d4ba638..5214f32 100644 --- a/doc/github-actions.md +++ b/doc/github-actions.md @@ -30,16 +30,18 @@ actions/setup-python@コミットハッシュ --- -## GitHub ActionsでSecretを扱う +## GitHub ActionsでSecret,variablesを扱う > GUIの場合は[公式ドキュメント](https://docs.github.com/ja/actions/security-guides/using-secrets-in-github-actions)参照。 -### 2種類のシークレット +### Secret + +#### 2種類のシークレット - Environment Secret: Environmentを作成して値を区別して使用できる。Environmentはリポジトリに対して複数作成できる。 - Repository Secret: リポジトリで共通の値を使う。 -### 使用方法(CLI) +#### 使用方法(CLI) > [GitHub CLIでリポジトリへsecretを設定する方法](https://zenn.dev/hankei6km/articles/set-secret-to-repo-with-githubcli) > [GitHub ActionsでEnvironment Secretを扱うサンプル](https://qiita.com/ak2ie/items/4fbcdf74e7760c49c1af) @@ -66,6 +68,18 @@ jobs: echo ${{ secrets.API_TOKEN }} ``` +### variables +- 基本はsecretと同じでenvironment variablesとrepository variablesがある。 +- secretと異なり,値を確認することができる。 + +#### 使用例 + +```shell +environment=development +gh variable set --env $environment --env-file .env.$environment +gh variable list --env $environment +``` + --- ## path filterを使って特定のファイル変更時のみCIを走らせる diff --git a/package-lock.json b/package-lock.json index a31e4ca..858eb3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@types/node": "^16.18.66", "@types/react": "^18.2.39", "@types/react-dom": "^18.2.17", + "dotenv": "^16.4.5", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", @@ -6053,11 +6054,14 @@ } }, "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, "node_modules/dotenv-cli": { @@ -6075,18 +6079,6 @@ "dotenv": "cli.js" } }, - "node_modules/dotenv-cli/node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, "node_modules/dotenv-cli/node_modules/dotenv-expand": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", @@ -13591,6 +13583,14 @@ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" }, + "node_modules/react-scripts/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-scripts/node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", diff --git a/package.json b/package.json index 9ac9860..6fe17e2 100644 --- a/package.json +++ b/package.json @@ -10,17 +10,23 @@ "@types/node": "^16.18.66", "@types/react": "^18.2.39", "@types/react-dom": "^18.2.17", + "dotenv": "^16.4.5", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" }, "scripts": { + "discription": "startはデフォルトで.env.developmentを使うがbuildはデフォルトで.env.productionを使う", "start": "react-scripts start", + "start-stg": "dotenv -e .env.staging react-scripts start", "start-prod": "dotenv -e .env.production react-scripts start", - "build": "react-scripts build", "build-dev": "dotenv -e .env.development react-scripts build", - "test": "react-scripts test", + "build-stg": "dotenv -e .env.staging react-scripts build", + "build": "react-scripts build", + "test-dev": "dotenv -e .env.development react-scripts test", + "test-stg": "dotenv -e .env.staging react-scripts test", + "test-prod": "dotenv -e .env.production react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { diff --git a/run_local.sh b/run_local_example.sh similarity index 63% rename from run_local.sh rename to run_local_example.sh index c36e1c0..08bae27 100755 --- a/run_local.sh +++ b/run_local_example.sh @@ -7,15 +7,18 @@ # Author: Ryosuke Tomita # Date: 2024/08/01 ########################################################################## -#docker rmi react-app:latest -f -#docker build -t react-app:latest . --no-cache -#docker run -p 80:8080 react-app:latest # -p localport:containerport +# -----composeを使わない場合----- +# docker build -t react-app:latest . --build-arg BUILD_ENV=production +# docker run -p 80:8080 react-app:latest # -p localport:containerport +# -----composeを使う----- # .env.developmentでbuildxでbuild docker buildx bake --set react-app.args.BUILD_ENV=development # .env.productionでbuildxでbuild # docker buildx bake --set react-app.args.BUILD_ENV=production - +# buildxを使わない場合の引数の設定方法 +#docker compose build --build-arg BUILD_ENV=production +# 起動 docker compose up # open your browser and go to `localhost:80`. diff --git a/src/App.css b/src/App.css index 74b5e05..a69922e 100644 --- a/src/App.css +++ b/src/App.css @@ -7,9 +7,11 @@ pointer-events: none; } +/* [`@media prefers-reduced-motion`](https://developer.mozilla.org/ja/docs/Web/CSS/@media/prefers-reduced-motion)はユーザがページの動きを少なくする設定時の動作を規定しており,no-preferenceになっているので該当時にはアニメーションは動きません。 */ @media (prefers-reduced-motion: no-preference) { .App-logo { animation: App-logo-spin infinite 20s linear; + /* animation: アニメーション名 無限ループ 1サイクルの速度(変えると回転速度が変わる) 一定速度で実行 */ } } @@ -28,7 +30,9 @@ color: #61dafb; } +/*[@keyframes](https://developer.mozilla.org/ja/docs/Web/CSS/@keyframes)はキーフレームを制御するため,fromとtoでアニメーションの始まりと終わりを定義している。*/ @keyframes App-logo-spin { + /* 360度回転する*/ from { transform: rotate(0deg); } diff --git a/src/App.tsx b/src/App.tsx index 0e4053c..51de2f2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import React from "react"; import logo from "./logo.svg"; import "./App.css"; -const message: string = process.env.REACT_APP_MESSAGE || "no env"; +const message: string = process.env.REACT_APP_MESSAGE || ""; function App() { return ( diff --git a/src/__tests__/App.test.tsx b/src/__tests__/App.test.tsx index 7f6509e..743cf92 100644 --- a/src/__tests__/App.test.tsx +++ b/src/__tests__/App.test.tsx @@ -1,10 +1,43 @@ +// import React from "react"; +// import { render, screen } from "@testing-library/react"; +// import App from "../App"; +// const message: string = process.env.REACT_APP_MESSAGE || ""; + +// // 画面にHello, Reactの文字が出るかテスト +// test("renders Hello, React link", () => { +// render(); +// const linkElement = screen.getByText(new RegExp(`Hello, React ${message}`, 'i')); +// expect(linkElement).toBeInTheDocument(); +// }); + import React from "react"; import { render, screen } from "@testing-library/react"; import App from "../App"; -// 画面にLearn Reactの文字が出るかテスト -test("renders learn react link", () => { +// 環境変数をテストの前に設定 +const originalEnv = process.env; +beforeEach(() => { + jest.resetModules(); // モジュールキャッシュをクリア + process.env = { ...originalEnv }; // 環境変数をリセット +}); + +afterAll(() => { + process.env = originalEnv; // 全テスト後に環境変数を元に戻す +}); + +// 画面に"Hello, React"の文字が出るかテスト(環境変数なし) +test("renders 'Hello, React' text without environment variable", () => { + process.env.REACT_APP_MESSAGE = ""; // 環境変数をクリア + render(); + const linkElement = screen.getByText(/Hello, React/i); + expect(linkElement).toBeInTheDocument(); +}); + +// 画面に"Hello, React"と環境変数のメッセージが出るかテスト(環境変数あり) +test("renders 'Hello, React' text with environment variable", () => { + const message: string = process.env.REACT_APP_MESSAGE || ""; + const testMessage: string = "Hello, React " + message; render(); - const linkElement = screen.getByText(/learn react/i); + const linkElement = screen.getByText(new RegExp(testMessage, "i")); expect(linkElement).toBeInTheDocument(); }); diff --git a/update_github_actoins_variables.sh b/update_github_actoins_variables.sh new file mode 100644 index 0000000..94f0928 --- /dev/null +++ b/update_github_actoins_variables.sh @@ -0,0 +1,7 @@ +#!/bin/bash +for environment in "development" "staging" "production"; +do + echo $environment + gh variable set --env $environment --env-file .env.$environment + gh variable list --env $environment +done