diff --git a/azure-pipelines-staging-ccb.yml b/azure-pipelines-staging-ccb.yml new file mode 100644 index 0000000..f4c7e80 --- /dev/null +++ b/azure-pipelines-staging-ccb.yml @@ -0,0 +1,312 @@ +# Pipeline側でKeyVaultやDocker、AppService等に対する操作権限を持ったServiceConenctionを作成しておくこと +# また、環境変数 STATIC_DICTATION_DEPLOYMENT_TOKEN の値として静的WebAppsのデプロイトークンを設定しておくこと +trigger: + branches: + include: + - release-ccb + tags: + include: + - stage-* + +jobs: +- job: initialize + displayName: Initialize + pool: + vmImage: ubuntu-latest + steps: + - checkout: self + clean: true + fetchDepth: 1 + persistCredentials: true + - script: | + git fetch origin release-ccb:release-ccb + if git merge-base --is-ancestor $(Build.SourceVersion) release-ccb; then + echo "This commit is in the release-ccb branch." + else + echo "This commit is not in the release-ccb branch." + exit 1 + fi + displayName: 'タグが付けられたCommitがrelease-ccbブランチに存在するか確認' +- job: backend_test + dependsOn: initialize + condition: succeeded('initialize') + displayName: UnitTest + pool: + vmImage: ubuntu-latest + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: Bash@3 + displayName: Bash Script (Test) + inputs: + targetType: inline + workingDirectory: dictation_server/.devcontainer + script: | + docker-compose -f pipeline-docker-compose.yml build + docker-compose -f pipeline-docker-compose.yml up -d + docker-compose exec -T dictation_server sudo npm ci + docker-compose exec -T dictation_server sudo npm run migrate:up:test + docker-compose exec -T dictation_server sudo npm run test +- job: backend_build + dependsOn: backend_test + condition: succeeded('backend_test') + displayName: Build And Push Backend Image + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: Npm@1 + displayName: npm ci + inputs: + command: ci + workingDir: dictation_server + verbose: false + - task: Docker@0 + displayName: build + inputs: + azureSubscriptionEndpoint: 'omds-service-connection-stg' + azureContainerRegistry: '{"loginServer":"crodmsregistrymaintenance.azurecr.io", "id" : "/subscriptions/108fb131-cdca-4729-a2be-e5bd8c0b3ba7/resourceGroups/maintenance-rg/providers/Microsoft.ContainerRegistry/registries/crOdmsRegistryMaintenance"}' + dockerFile: DockerfileServerDictation.dockerfile + imageName: odmscloud/staging/dictation:$(Build.SourceVersion) + buildArguments: | + BUILD_VERSION=$(Build.SourceVersion) + - task: Docker@0 + displayName: push + inputs: + azureSubscriptionEndpoint: 'omds-service-connection-stg' + azureContainerRegistry: '{"loginServer":"crodmsregistrymaintenance.azurecr.io", "id" : "/subscriptions/108fb131-cdca-4729-a2be-e5bd8c0b3ba7/resourceGroups/maintenance-rg/providers/Microsoft.ContainerRegistry/registries/crOdmsRegistryMaintenance"}' + action: Push an image + imageName: odmscloud/staging/dictation:$(Build.SourceVersion) +- job: frontend_build_staging + dependsOn: backend_build + condition: succeeded('backend_build') + displayName: Build Frontend Files(staging) + variables: + storageAccountName: saomdspipeline + environment: staging + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: Npm@1 + displayName: npm ci + inputs: + command: ci + workingDir: dictation_client + verbose: false + - task: Bash@3 + displayName: Bash Script + inputs: + targetType: inline + script: cd dictation_client && npm run build:stg + - task: ArchiveFiles@2 + inputs: + rootFolderOrFile: dictation_client/build + includeRootFolder: false + archiveType: 'zip' + archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.SourceVersion).zip' + replaceExistingArchive: true + - task: AzureCLI@2 + inputs: + azureSubscription: 'omds-service-connection-stg' + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az storage blob upload \ + --auth-mode login \ + --account-name $(storageAccountName) \ + --container-name $(environment) \ + --name $(Build.SourceVersion).zip \ + --type block \ + --overwrite \ + --file $(Build.ArtifactStagingDirectory)/$(Build.SourceVersion).zip +- job: function_test + dependsOn: frontend_build_staging + condition: succeeded('frontend_build_staging') + displayName: UnitTest + pool: + vmImage: ubuntu-latest + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: Bash@3 + displayName: Bash Script (Test) + inputs: + targetType: inline + workingDirectory: dictation_function/.devcontainer + script: | + docker-compose -f pipeline-docker-compose.yml build + docker-compose -f pipeline-docker-compose.yml up -d + docker-compose exec -T dictation_function sudo npm ci + docker-compose exec -T dictation_function sudo npm run test +- job: function_build + dependsOn: function_test + condition: succeeded('function_test') + displayName: Build And Push Function Image + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: Npm@1 + displayName: npm ci + inputs: + command: ci + workingDir: dictation_function + verbose: false + - task: Docker@0 + displayName: build + inputs: + azureSubscriptionEndpoint: 'omds-service-connection-stg' + azureContainerRegistry: '{"loginServer":"crodmsregistrymaintenance.azurecr.io", "id" : "/subscriptions/108fb131-cdca-4729-a2be-e5bd8c0b3ba7/resourceGroups/maintenance-rg/providers/Microsoft.ContainerRegistry/registries/crOdmsRegistryMaintenance"}' + dockerFile: DockerfileFunctionDictation.dockerfile + imageName: odmscloud/staging/dictation_function:$(Build.SourceVersion) + buildArguments: | + BUILD_VERSION=$(Build.SourceVersion) + - task: Docker@0 + displayName: push + inputs: + azureSubscriptionEndpoint: 'omds-service-connection-stg' + azureContainerRegistry: '{"loginServer":"crodmsregistrymaintenance.azurecr.io", "id" : "/subscriptions/108fb131-cdca-4729-a2be-e5bd8c0b3ba7/resourceGroups/maintenance-rg/providers/Microsoft.ContainerRegistry/registries/crOdmsRegistryMaintenance"}' + action: Push an image + imageName: odmscloud/staging/dictation_function:$(Build.SourceVersion) +- job: backend_deploy + dependsOn: function_build + condition: succeeded('function_build') + displayName: Backend Deploy + pool: + vmImage: ubuntu-latest + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: AzureWebAppContainer@1 + inputs: + azureSubscription: 'omds-service-connection-stg' + appName: 'app-odms-dictation-stg' + deployToSlotOrASE: true + resourceGroupName: 'stg-application-rg' + slotName: 'staging' + containers: 'crodmsregistrymaintenance.azurecr.io/odmscloud/staging/dictation:$(Build.SourceVersion)' +- job: frontend_deploy + dependsOn: backend_deploy + condition: succeeded('backend_deploy') + displayName: Deploy Frontend Files + variables: + storageAccountName: saomdspipeline + environment: staging + pool: + vmImage: ubuntu-latest + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: AzureCLI@2 + inputs: + azureSubscription: 'omds-service-connection-stg' + scriptType: 'bash' + scriptLocation: 'inlineScript' + inlineScript: | + az storage blob download \ + --auth-mode login \ + --account-name $(storageAccountName) \ + --container-name $(environment) \ + --name $(Build.SourceVersion).zip \ + --file $(Build.SourcesDirectory)/$(Build.SourceVersion).zip + - task: Bash@3 + displayName: Bash Script + inputs: + targetType: inline + script: unzip $(Build.SourcesDirectory)/$(Build.SourceVersion).zip -d $(Build.SourcesDirectory)/$(Build.SourceVersion) + - task: AzureStaticWebApp@0 + displayName: 'Static Web App: ' + inputs: + workingDirectory: '$(Build.SourcesDirectory)' + app_location: '/$(Build.SourceVersion)' + config_file_location: /dictation_client + skip_app_build: true + skip_api_build: true + is_static_export: false + verbose: false + azure_static_web_apps_api_token: $(STATIC_DICTATION_DEPLOYMENT_TOKEN) +- job: function_deploy + dependsOn: frontend_deploy + condition: succeeded('frontend_deploy') + displayName: Function Deploy + pool: + vmImage: ubuntu-latest + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: AzureFunctionAppContainer@1 + inputs: + azureSubscription: 'omds-service-connection-stg' + appName: 'func-odms-dictation-stg' + imageName: 'crodmsregistrymaintenance.azurecr.io/odmscloud/staging/dictation_function:$(Build.SourceVersion)' +- job: smoke_test + dependsOn: function_deploy + condition: succeeded('function_deploy') + displayName: 'smoke test' + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + # スモークテスト用にjobを確保 +- job: swap_slot + dependsOn: smoke_test + condition: succeeded('smoke_test') + displayName: 'Swap Staging and Production' + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: AzureAppServiceManage@0 + displayName: 'Azure App Service Manage: app-odms-dictation-stg' + inputs: + azureSubscription: 'omds-service-connection-stg' + action: 'Swap Slots' + WebAppName: 'app-odms-dictation-stg' + ResourceGroupName: 'stg-application-rg' + SourceSlot: 'staging' + SwapWithProduction: true +- job: migration + dependsOn: swap_slot + condition: succeeded('swap_slot') + displayName: DB migration + pool: + name: odms-deploy-pipeline + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: AzureKeyVault@2 + displayName: 'Azure Key Vault: kv-odms-secret-stg' + inputs: + ConnectedServiceName: 'omds-service-connection-stg' + KeyVaultName: kv-odms-secret-stg + - task: CmdLine@2 + displayName: migration + inputs: + script: >2 + # DB接続情報書き換え + sed -i -e "s/DB_NAME_CCB/$(db-name-ccb)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_PASS/$(admin-db-pass)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_USERNAME/$(admin-db-user)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_PORT/$(db-port)/g" ./dictation_server/db/dbconfig.yml + sed -i -e "s/DB_HOST/$(db-host)/g" ./dictation_server/db/dbconfig.yml + sql-migrate --version + cat ./dictation_server/db/dbconfig.yml + # migration実行 + sql-migrate up -config=./dictation_server/db/dbconfig.yml -env=ci_ccb \ No newline at end of file diff --git a/dictation_function/src/database/initializeDataSource.ts b/dictation_function/src/database/initializeDataSource.ts index 45cb3b9..f323d54 100644 --- a/dictation_function/src/database/initializeDataSource.ts +++ b/dictation_function/src/database/initializeDataSource.ts @@ -22,7 +22,7 @@ export async function initializeDataSource( port: Number(process.env.DB_PORT), username: process.env.DB_USERNAME, password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, + database: process.env.DB_NAME_CCB, entities: [ User, UserArchive, diff --git a/dictation_server/db/dbconfig.yml b/dictation_server/db/dbconfig.yml index 38bd96b..48f97aa 100644 --- a/dictation_server/db/dbconfig.yml +++ b/dictation_server/db/dbconfig.yml @@ -10,7 +10,11 @@ ci: dialect: mysql dir: ./dictation_server/db/migrations datasource: DB_USERNAME:DB_PASS@tcp(DB_HOST:DB_PORT)/DB_NAME?charset=utf8mb4&collation=utf8mb4_0900_ai_ci&parseTime=true +ci_ccb: + dialect: mysql + dir: ./dictation_server/db/migrations + datasource: DB_USERNAME:DB_PASS@tcp(DB_HOST:DB_PORT)/DB_NAME_CCB?charset=utf8mb4&collation=utf8mb4_0900_ai_ci&parseTime=true test: dialect: mysql dir: /app/dictation_server/db/migrations - datasource: user:password@tcp(test_mysql_db:3306)/odms?charset=utf8mb4&collation=utf8mb4_0900_ai_ci&parseTime=true \ No newline at end of file + datasource: user:password@tcp(test_mysql_db:3306)/odms?charset=utf8mb4&collation=utf8mb4_0900_ai_ci&parseTime=true diff --git a/dictation_server/src/app.module.ts b/dictation_server/src/app.module.ts index 3a8dfd5..f35fe54 100644 --- a/dictation_server/src/app.module.ts +++ b/dictation_server/src/app.module.ts @@ -60,10 +60,10 @@ import { CheckHeaderMiddleware } from './common/check-header.middleware'; useFactory: () => process.env.STAGE === 'local' ? [ - { - rootPath: join(__dirname, '..', 'build'), - }, - ] + { + rootPath: join(__dirname, '..', 'build'), + }, + ] : [], }), ConfigModule.forRoot({ @@ -100,7 +100,7 @@ import { CheckHeaderMiddleware } from './common/check-header.middleware'; port: configService.get('DB_PORT'), username: configService.get('DB_USERNAME'), password: configService.get('DB_PASSWORD'), - database: configService.get('DB_NAME'), + database: configService.get('DB_NAME_CCB'), autoLoadEntities: true, // forFeature()で登録されたEntityを自動的にロード synchronize: false, // trueにすると自動的にmigrationが行われるため注意 }),