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 4d29575..061e554 100644 --- a/.gitignore +++ b/.gitignore @@ -13,10 +13,11 @@ # misc .DS_Store -.env.local -.env.development.local +.env +.env.development .env.test.local -.env.production.local +.env.production +.env.staging npm-debug.log* yarn-debug.log* diff --git a/Dockerfile b/Dockerfile index ef92675..a861e58 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,30 @@ # Build Image FROM node:20 AS build WORKDIR /app + +# defaultをdevelopmentにし,引数でproductionにも切り替えられるようにする +ARG BUILD_ENV=development + COPY . . -RUN npm install && npm run build + +# npm startは.env.developmentが優先されるがnpm run buildでは.env.productoinが優先されるので注意。 +RUN < [!WARNING] +> Since it costs money to maintain the AWS environment created with copilot-cli for the demo environment, I plan to use `GitHub-Pages` for future demos. I have archived [this branch](https://github.com/RyosukeDTomita/devsecops-demo-aws-ecs). +> デモ環境に対して`copilot-cli`で作ったAWS環境を維持するのにお金がかかるのはもったいないので,以降は`github-pages`を使ってデモを動かそうと思います。[このブランチ](https://github.com/RyosukeDTomita/devsecops-demo-aws-ecs)をアーカイブを残してあります。 + 1. [PREPARING](#preparing)の設定を先にやる。 2. commit時にはpre-commitとgit-secretが作動。 3. push時にはGitHub ActionsによりSAST(semgrep),UnitTest(jest),Dependency Check(trivy)が実行される。 -4. masterブランチにマージしたりmasterにpushした時にCodePipelineによってAWSへリポジトリがクローンされ,ビルド(image scanを含む),developmentへのデプロイが始まる。 -5. developmentで問題がなければCodePipeline上で承認し,productionへデプロイ +4. github-pagesにデプロイされる。 # TODO: more info ## ENVIRONMENT @@ -37,7 +40,7 @@ Sample React application for Trying to Use DevSecOps tools. - [ghalint](./doc/tools_doc/ghalint.md): GitHub Actionsで実行されるworkflows用のlinter - [github-comment](./doc/tools_doc/github-comment.md): GitHub Actionsで実行されるCIが失敗したときにコメントとしてエラーを出力する。 - [semgrep](./doc/tools_doc/semgrep.md): GitHub Actionsで実行するSASTツール -- [trivy](./doc/tools_doc/trivy.md): イメージのスキャンやdependency checkができる。dependency checkはGitHub Actionsで実行,イメージスキャンはAWS Code Pipelineで実行。 +- [trivy](./doc/tools_doc/trivy.md): イメージのスキャンやdependency checkができる。dependency checkはGitHub Actionsで実行,イメージスキャンは#TODO - [aqua](./doc/tools_doc/aqua.md): GitHub Actionsで使用するCLIツールのバージョン管理ができる。 - [pinact](./doc/tools_doc/pinact.md): GitHub Actionsで使うactionsのバージョンをフルコミットハッシュに変換。 @@ -63,107 +66,82 @@ Sample React application for Trying to Use DevSecOps tools. --- -### AWSの構成 - -AWS: ECS on FargateにCode Pipeline経由でデプロイする。サンプルではdevとprod環境を用意し、dev環境で動作確認後に承認ボタンを押すとprod環境のデプロイが進む形になっている。 - -- app-infrastructure-roles - ![app-infrastructure-roles](./doc/fig/cfn/app-infrastructure-roles.png) -- app-infrastructure - ![app-infrastructure](./doc/fig/cfn/app-infrastructure.png) -- environment - ![env](./doc/fig/cfn/env.png) -- service - ![svc](./doc/fig/cfn/svc.png) -- pipeline - ![pipeline](./doc/fig/cfn/pipeline.png) - ---- - ## PREPARING -### AWSの設定 +### 始めにやること -[initialsettings_aws](./initialsettings_aws.md)を参照。 +- Reopsitoryをforkする。 ---- +### ローカルにインストールするツール -## HOW TO USE +- `pre-commit` +- `git secret` +- `gh`コマンドのインストール +- VSCodeのExtensionsもお好みでインストール。TODO: Devcontainer化する。 -- [PREPARING](#preparing)をやる。 -- ローカルでのセットアップが必用なのは git-secretsのセットアップ。 +### GitHub Actionsでghコマンドを使うための設定 -```shell -cd devsecops-demo-aws-ecs -pre-commit install +- [Personal access tokens](https://github.com/settings/tokens)を作り,repository secretsに登録する。 +TODO: 一旦これくらいで作成。もっと権限しぼれるかも +![personal acccess token例](./doc/fig/pat.png) +- repository secretsに登録する。 +![Actions secrets and variables](./doc/fig/actions-secrets-set.png) -git secrets --install -git secrets --register-aws # awsのクレデンシャル検知ルールを登録 -``` +### GitHub Actions Variablesの設定 -- pre-commitのセットアップ +- Repositoryに[Environment](https://github.com/RyosukeDTomita/devsecops-demo-aws-ecs/settings/environments)を作る。 +![Environment例](./doc/fig/github-environment.png) +- ローカルに3環境分の.envファイルをを作成する。 ```shell -pip install pre-commit -pre-commit install +# 作成 +for environment in development staging production; +do + touch .env.${environment} + echo $REACT_APP_MESSAGE=${environment} > .env.${environment} +done ``` -- VSCodeのExtensionsもお好みでインストール。 -- GitHub Actionsがスキャン結果のファイルをアップロードできるように権限をつける。詳細は[semgrepのyaml](./.github/workflows/react-semgrep.yaml)を参照。 - ---- - -## ERROR LOG - -
-今まで詰まったエラー一覧
- -### Code Build のエラー - -以下コマンドでログが見られる。ブラウザのAWS Code Deploy +- github actions enrironment variablesに登録/更新する。 ```shell -copilot svc logs --previous +source ./update_github_actions_variables.sh ``` -#### nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied) +### GitHub Actionsで実行したスキャン結果をアップロードできるようにGitHubリポジトリの設定を変更する -- [ECS の仕様で非特権ユーザを使用したコンテナでは 80 番ポートが使えないっぽい](https://repost.aws/questions/QU1bCV9wT4T5iBrrP1c2ISfg/container-cannot-bind-to-port-80-running-as-non-root-user-on-ecs-fargate) --> つまり,localのdockerで80でサービスが起動できてもECSだと権限エラーになる。このため,コンテナで開放するportは8080としている(ALBに対して8080がマッピングされているためブラウザからは80でアクセスできる)。 +- GitHub Actionsがスキャン結果のファイルをアップロードできるようにGitHubリポジトリの設定を変更。詳細は[semgrepのyaml](./.github/workflows/react-semgrep.yaml)を参照。 -#### toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: +--- -- Docker Hubに短期間にアクセスしすぎているだけなので放置でOK +## HOW TO USE -#### Error response from daemon: dockerfile parse error +### コミット時の検査セットアップ -- DockerfileのRUNをヒアドキュメントで書いていたら怒られた(ローカルでは動いてたのに...) +- git-secretsのセットアップ。 -```dockerfile -# 修正前Dockerfile -RUN <
+
+今まで詰まったエラー一覧 +
+TODO +
+
diff --git a/copilot/.workspace b/copilot/.workspace deleted file mode 100644 index a9afdd4..0000000 --- a/copilot/.workspace +++ /dev/null @@ -1 +0,0 @@ -application: react-app diff --git a/copilot/dev-svc/manifest.yml b/copilot/dev-svc/manifest.yml deleted file mode 100644 index fe3a5f3..0000000 --- a/copilot/dev-svc/manifest.yml +++ /dev/null @@ -1,47 +0,0 @@ -# The manifest for the "dev-svc" service. -# Read the full specification for the "Load Balanced Web Service" type at: -# https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/ - -# Your service name will be used in naming your resources like log groups, ECS services, etc. -name: dev-svc -type: Load Balanced Web Service - -# Distribute traffic to your service. -http: - # Requests to this path will be forwarded to your service. - # To match all requests you can use the "/" path. - path: '/' - # You can specify a custom health check path. The default is "/". - # healthcheck: '/' - -# Configuration for your containers and service. -image: - # Docker build arguments. For additional overrides: https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#image-build - build: Dockerfile - # Port exposed through your container to route traffic to it. - port: 8080 - -cpu: 256 # Number of CPU units for the task. -memory: 512 # Amount of memory in MiB used by the task. -count: 1 # Number of tasks that should be running in your service. -exec: true # Enable running commands in your container. -network: - connect: true # Enable Service Connect for intra-environment traffic between services. - -# storage: - # readonly_fs: true # Limit to read-only access to mounted root filesystems. - -# Optional fields for more advanced use-cases. -# -#variables: # Pass environment variables as key value pairs. -# LOG_LEVEL: info - -#secrets: # Pass secrets from AWS Systems Manager (SSM) Parameter Store. -# GITHUB_TOKEN: GITHUB_TOKEN # The key is the name of the environment variable, the value is the name of the SSM parameter. - -# You can override any of the values defined above by environment. -#environments: -# test: -# count: 2 # Number of tasks to run for the "test" environment. -# deployment: # The deployment strategy for the "test" environment. -# rolling: 'recreate' # Stops existing tasks before new ones are started for faster deployments. diff --git a/copilot/environments/dev-env/manifest.yml b/copilot/environments/dev-env/manifest.yml deleted file mode 100644 index 1c14f97..0000000 --- a/copilot/environments/dev-env/manifest.yml +++ /dev/null @@ -1,21 +0,0 @@ -# The manifest for the "dev-env" environment. -# Read the full specification for the "Environment" type at: -# https://aws.github.io/copilot-cli/docs/manifest/environment/ - -# Your environment name will be used in naming your resources like VPC, cluster, etc. -name: dev-env -type: Environment - -# Import your own VPC and subnets or configure how they should be created. -# network: -# vpc: -# id: - -# Configure the load balancers in your environment, once created. -# http: -# public: -# private: - -# Configure observability for your environment resources. -observability: - container_insights: false diff --git a/copilot/environments/prod-env/manifest.yml b/copilot/environments/prod-env/manifest.yml deleted file mode 100644 index 8102c47..0000000 --- a/copilot/environments/prod-env/manifest.yml +++ /dev/null @@ -1,28 +0,0 @@ -# The manifest for the "prod-env" environment. -# Read the full specification for the "Environment" type at: -# https://aws.github.io/copilot-cli/docs/manifest/environment/ - -# Your environment name will be used in naming your resources like VPC, cluster, etc. -name: prod-env -type: Environment - -# Import your own VPC and subnets or configure how they should be created. -network: - vpc: - id: vpc-0e2c3939c6159987c - subnets: - public: - - id: subnet-077af848ce2255562 - - id: subnet-074c71e5fac150d04 - private: - - id: subnet-0c572ccc92f2f825f - - id: subnet-0209edab730676d3e - -# Configure the load balancers in your environment, once created. -# http: -# public: -# private: - -# Configure observability for your environment resources. -observability: - container_insights: false diff --git a/copilot/pipelines/react-app-pipeline/buildspec.yml b/copilot/pipelines/react-app-pipeline/buildspec.yml deleted file mode 100644 index 5d35eae..0000000 --- a/copilot/pipelines/react-app-pipeline/buildspec.yml +++ /dev/null @@ -1,75 +0,0 @@ -# Buildspec runs in the build stage of your pipeline. -version: 0.2 -phases: - install: - commands: - - echo "cd into $CODEBUILD_SRC_DIR" - - cd $CODEBUILD_SRC_DIR - # Download the copilot linux binary. - - wget -q https://ecs-cli-v2-release.s3.amazonaws.com/copilot-linux-v1.32.0 -O copilot-linux - - chmod +x ./copilot-linux - # Download trivy. https://aquasecurity.github.io/trivy/v0.48/getting-started/installation/ - - echo "install trivy" - - rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v0.48.0/trivy_0.48.0_Linux-64bit.rpm - - build: - commands: - - echo "Run your tests" - # - make test - post_build: - commands: - - ls -l - - export COLOR="false" - - export CI="true" - - pipeline=$(cat $CODEBUILD_SRC_DIR/copilot/pipelines/react-app-pipeline/manifest.yml | ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load(ARGF))') - - pl_envs=$(echo $pipeline | jq -r '.stages[].name') - # Find all the local services in the workspace. - - svc_ls_result=$(./copilot-linux svc ls --local --json) - - svc_list=$(echo $svc_ls_result | jq '.services') - - > - if [ ! "$svc_list" = null ]; then - svcs=$(echo $svc_ls_result | jq -r '.services[].name'); - fi - # Find all the local jobs in the workspace. - - job_ls_result=$(./copilot-linux job ls --local --json) - - job_list=$(echo $job_ls_result | jq '.jobs') - - > - if [ ! "$job_list" = null ]; then - jobs=$(echo $job_ls_result | jq -r '.jobs[].name'); - fi - # Raise error if no services or jobs are found. - - > - if [ "$svc_list" = null ] && [ "$job_list" = null ]; then - echo "No services or jobs found for the pipeline to deploy. Please create at least one service or job and push the manifest to the remote." 1>&2; - exit 1; - fi - # Generate the cloudformation templates. - # The tag is the build ID but we replaced the colon ':' with a dash '-'. - # We truncate the tag (from the front) to 128 characters, the limit for Docker tags - # (https://docs.docker.com/engine/reference/commandline/tag/) - # Check if the `svc package` commanded exited with a non-zero status. If so, echo error msg and exit. - - > - for env in $pl_envs; do - tag=$(echo ${CODEBUILD_BUILD_ID##*:}-$env | sed 's/:/-/g' | rev | cut -c 1-128 | rev) - for svc in $svcs; do - ./copilot-linux svc package -n $svc -e $env --output-dir './infrastructure' --tag $tag --upload-assets; - if [ $? -ne 0 ]; then - echo "Cloudformation stack and config files were not generated. Please check build logs to see if there was a manifest validation error." 1>&2; - exit 1; - fi - done; - for job in $jobs; do - ./copilot-linux job package -n $job -e $env --output-dir './infrastructure' --tag $tag --upload-assets; - if [ $? -ne 0 ]; then - echo "Cloudformation stack and config files were not generated. Please check build logs to see if there was a manifest validation error." 1>&2; - exit 1; - fi - done; - done; - - ls -lah ./infrastructure - # Run trivy scan on the docker images. - - trivy image --vuln-type os --no-progress --format table -o container-scanning-report.txt --severity CRITICAL,HIGH $(jq -r '.Parameters.ContainerImage' ./infrastructure/dev-svc-dev-env.params.json) - - cat container-scanning-report.txt -artifacts: - files: - - "infrastructure/*" diff --git a/copilot/pipelines/react-app-pipeline/manifest.yml b/copilot/pipelines/react-app-pipeline/manifest.yml deleted file mode 100644 index 3bd89b3..0000000 --- a/copilot/pipelines/react-app-pipeline/manifest.yml +++ /dev/null @@ -1,37 +0,0 @@ -# The manifest for the "react-app-pipeline" pipeline. -# This YAML file defines your pipeline: the source repository it tracks and the order of the environments to deploy to. -# For more info: https://aws.github.io/copilot-cli/docs/manifest/pipeline/ - -# The name of the pipeline. -name: react-app-pipeline - -# The version of the schema used in this template. -version: 1 - -# This section defines your source, changes to which trigger your pipeline. -source: - # The name of the provider that is used to store the source artifacts. - # (i.e. GitHub, Bitbucket, CodeCommit) - provider: GitHub - # Additional properties that further specify the location of the artifacts. - properties: - branch: master - repository: https://github.com/RyosukeDTomita/devsecops-demo-aws-ecs - # Optional: specify the name of an existing CodeStar Connections connection. - # connection_name: a-connection - -# This section defines the order of the environments your pipeline will deploy to. -stages: - - # The name of the environment. - name: dev-env - # Optional: flag for manual approval action before deployment. - # requires_approval: true - # Optional: use test commands to validate this stage of your build. - # test_commands: [echo 'running tests', make test] - - - # The name of the environment. - name: prod-env - # Optional: flag for manual approval action before deployment. - requires_approval: true - # Optional: use test commands to validate this stage of your build. - # test_commands: [echo 'running tests', make test] diff --git a/copilot/prod-svc/manifest.yml b/copilot/prod-svc/manifest.yml deleted file mode 100644 index 79d94e4..0000000 --- a/copilot/prod-svc/manifest.yml +++ /dev/null @@ -1,47 +0,0 @@ -# The manifest for the "prod-svc" service. -# Read the full specification for the "Load Balanced Web Service" type at: -# https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/ - -# Your service name will be used in naming your resources like log groups, ECS services, etc. -name: prod-svc -type: Load Balanced Web Service - -# Distribute traffic to your service. -http: - # Requests to this path will be forwarded to your service. - # To match all requests you can use the "/" path. - path: 'prod-svc' - # You can specify a custom health check path. The default is "/". - # healthcheck: '/' - -# Configuration for your containers and service. -image: - # Docker build arguments. For additional overrides: https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#image-build - build: Dockerfile - # Port exposed through your container to route traffic to it. - port: 8080 - -cpu: 256 # Number of CPU units for the task. -memory: 512 # Amount of memory in MiB used by the task. -count: 1 # Number of tasks that should be running in your service. -exec: true # Enable running commands in your container. -network: - connect: true # Enable Service Connect for intra-environment traffic between services. - -# storage: - # readonly_fs: true # Limit to read-only access to mounted root filesystems. - -# Optional fields for more advanced use-cases. -# -#variables: # Pass environment variables as key value pairs. -# LOG_LEVEL: info - -#secrets: # Pass secrets from AWS Systems Manager (SSM) Parameter Store. -# GITHUB_TOKEN: GITHUB_TOKEN # The key is the name of the environment variable, the value is the name of the SSM parameter. - -# You can override any of the values defined above by environment. -#environments: -# test: -# count: 2 # Number of tasks to run for the "test" environment. -# deployment: # The deployment strategy for the "test" environment. -# rolling: 'recreate' # Stops existing tasks before new ones are started for faster deployments. 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/doc/tools_doc/pre-commit.md b/doc/tools_doc/pre-commit.md index a35848e..d418cf2 100644 --- a/doc/tools_doc/pre-commit.md +++ b/doc/tools_doc/pre-commit.md @@ -12,7 +12,11 @@ pip install pre-commit pre-commit sample-config > .pre-commit-config.yaml # すでに本リポジトリでは作成済み pre-commit install + +# ローカルでとりあえず動かしてみる。 +pre-commit run -a ``` +うまく動作してそうなら今後git commit時にツールが動作する。 ### インストール時のエラー diff --git a/docker_test.sh b/docker_test.sh deleted file mode 100755 index 4d1f42d..0000000 --- a/docker_test.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -########################################################################## -# Name: docker_test.sh -# -# Usage: Dockerfile build test. This scripts only used local computer. -# -# Author: Ryosuke Tomita -# Date: 2023/12/06 -########################################################################## -#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 -docker compose up - -# open your browser and go to `localhost:80`. diff --git a/package-lock.json b/package-lock.json index 0359006..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", @@ -22,6 +23,7 @@ }, "devDependencies": { "@typescript-eslint/parser": "^5.62.0", + "dotenv-cli": "^7.4.2", "eslint": "^8.54.0", "prettier": "^2.8.8", "typescript": "^4.9.5" @@ -6052,11 +6054,38 @@ } }, "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-cli": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.4.2.tgz", + "integrity": "sha512-SbUj8l61zIbzyhIbg0FwPJq6+wjbzdn9oEtozQpZ6kW2ihCcapKVZj49oCT3oPM+mgQm+itgvUQcG5szxVrZTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "dotenv": "^16.3.0", + "dotenv-expand": "^10.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "dotenv": "cli.js" + } + }, + "node_modules/dotenv-cli/node_modules/dotenv-expand": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", + "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/dotenv-expand": { @@ -13554,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 9dee296..6fe17e2 100644 --- a/package.json +++ b/package.json @@ -10,15 +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-dev": "dotenv -e .env.development react-scripts build", + "build-stg": "dotenv -e .env.staging react-scripts build", "build": "react-scripts build", - "test": "react-scripts test", + "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": { @@ -41,6 +49,7 @@ }, "devDependencies": { "@typescript-eslint/parser": "^5.62.0", + "dotenv-cli": "^7.4.2", "eslint": "^8.54.0", "prettier": "^2.8.8", "typescript": "^4.9.5" diff --git a/pre-commit-test-local.sh b/pre-commit-test-local.sh deleted file mode 100644 index 331311d..0000000 --- a/pre-commit-test-local.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -pre-commit install -pre-commit run -a diff --git a/run_local_example.sh b/run_local_example.sh new file mode 100755 index 0000000..08bae27 --- /dev/null +++ b/run_local_example.sh @@ -0,0 +1,24 @@ +#!/bin/bash +########################################################################## +# Name: run_local.sh +# +# Usage: Dockerfile build test. This scripts only used local computer. +# +# Author: Ryosuke Tomita +# Date: 2024/08/01 +########################################################################## +# -----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 9cc63d9..51de2f2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,7 @@ import React from "react"; import logo from "./logo.svg"; import "./App.css"; +const message: string = process.env.REACT_APP_MESSAGE || ""; function App() { return ( @@ -16,7 +17,7 @@ function App() { target="_blank" rel="noopener noreferrer" > - Learn React + Hello, React {message} 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