diff --git a/.github/workflows/dispatch_release_hotfix.yaml b/.github/workflows/dispatch_release_hotfix.yaml new file mode 100644 index 0000000000..581ee1556b --- /dev/null +++ b/.github/workflows/dispatch_release_hotfix.yaml @@ -0,0 +1,239 @@ +name: "[Dispatch] Release Hotfix" + +on: + workflow_dispatch: + inputs: + version: + description: 'enter version(x.y.z-fix.{a})' + required: true + default: '2.0.0' + container_arch: + type: choice + description: 'choose container architecture' + default: linux/amd64 + options: + - "linux/amd64" + - "linux/amd64,linux/arm64" + + +env: + ARCH: ${{ github.event.inputs.container_arch }} + VERSION: ${{ github.event.inputs.version }} + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} + BRANCH_PREFIX: "hotfix-" + +jobs: + check-branch: + runs-on: ubuntu-latest + steps: + - name: Check branch with regex + run: | + if [[ ! "${{ github.ref }}" =~ ^refs/heads/(${{env.BRANCH_PREFIX}}.*)$ ]]; then + echo `::error::Branch should always be run from '${{env.BRANCH_PREFIX}}', Running branch: ${github.ref_name}`. + exit 1 + fi + - name: Notice when job fails + if: failure() + uses: 8398a7/action-slack@v3.15.0 + with: + status: ${{job.status}} + fields: repo,workflow,job + author_name: Github Action Slack + + mirinae: + runs-on: ubuntu-latest + needs: check-branch + steps: + - name: Invoke mirinae release workflow + id: mirinae + uses: convictional/trigger-workflow-and-wait@v1.6.1 + with: + owner: ${{ github.repository_owner }} + repo: ${{ github.event.repository.name }} + github_token: ${{ secrets.PAT_TOKEN }} + workflow_file_name: dispatch_mirinae_release.yaml + wait_workflow: true + propagate_failure: true + wait_interval: 5 + ref: ${{ github.ref_name }} + + storybook: + runs-on: ubuntu-latest + needs: mirinae + steps: + - name: Invoke storybook release workflow + uses: convictional/trigger-workflow-and-wait@v1.6.1 + with: + owner: ${{ github.repository_owner }} + repo: ${{ github.event.repository.name }} + github_token: ${{ secrets.PAT_TOKEN }} + workflow_file_name: dispatch_storybook_release.yaml + wait_workflow: false + propagate_failure: false + ref: ${{ github.ref_name }} + + versioning_and_docker: + runs-on: ubuntu-latest + needs: mirinae + outputs: + new_commit_sha: ${{ steps.get_sha.outputs.NEW_COMMIT_SHA }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + ref: ${{ github.ref_name }} + token: ${{ secrets.PAT_TOKEN }} + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: 16 + + - name: Restore cached node_modules + id: restore-node-cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.OS }}-node-modules-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.OS }}-node-modules- + + - name: Install dependencies + if: steps.restore-node-cache.outputs.cache-hit != 'true' + run: npm ci + + - name: Change version + run: | + converted_version=$(echo ${{ env.VERSION }} | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+-fix\.[0-9]+)/\1/') + npm version $converted_version --no-git-tag-version --allow-same-version --no-commit-hooks --include-workspace-root -w=web + echo "converted_version=$converted_version" >> "$GITHUB_OUTPUT" + + - name: Import GPG key + id: import-gpg + uses: crazy-max/ghaction-import-gpg@v6.2.0 + with: + gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.GPG_PASSPHRASE }} + git_user_signingkey: true + git_commit_gpgsign: true + + - name: Configure git + run: | + git config --global user.signingkey "${{ secrets.CLOUDFORET_ADMIN_GPG_KEY_ID }}" + git config --global user.email "${{ vars.GIT_EMAIL }}" + git config --global user.name "${{ vars.GIT_USERNAME }}" + + - name: Check if there are any changes + id: check_changes + run: | + git diff --exit-code --quiet || echo "::set-output name=changed::true" + continue-on-error: true + + - name: Commit changes and Set current commit SHA to output + if: steps.check_changes.outputs.changed == 'true' + id: get_sha + run: | + git commit -s -am "chore: version ${{ env.VERSION }}" + echo "NEW_COMMIT_SHA=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT" + env: + GIT_AUTHOR_NAME: ${{ steps.import-gpg.outputs.name }} + GIT_AUTHOR_EMAIL: ${{ steps.import-gpg.outputs.email }} + GIT_COMMITTER_NAME: ${{ steps.import-gpg.outputs.name }} + GIT_COMMITTER_EMAIL: ${{ steps.import-gpg.outputs.email }} + + - name: Push changes + if: steps.check_changes.outputs.changed == 'true' + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.PAT_TOKEN }} + branch: ${{ github.ref }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.CLOUDFORET_DEV_DOCKER_USERNAME }} + password: ${{ secrets.CLOUDFORET_DEV_DOCKER_PASSWORD }} + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-east-1 + + - name: Login to Amazon ECR + run: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${{ secrets.ECR_REPO }} + + - name: Build and push to dockerhub + uses: docker/build-push-action@v4 + env: + BUILDKIT_COLORS: 1 + with: + context: . + file: ./apps/web/Dockerfile + platforms: ${{ env.ARCH }} + push: true + cache-from: ${{ vars.DOCKER_REPO_OWNER }}/${{ github.event.repository.name }}:latest + cache-to: type=inline + tags: | + ${{ vars.DOCKER_REPO_OWNER }}/${{ github.event.repository.name }}:latest + ${{ vars.DOCKER_REPO_OWNER }}/${{ github.event.repository.name }}:${{ env.VERSION }} + ${{ secrets.ECR_REPO }}/${{ github.event.repository.name }}:latest + ${{ secrets.ECR_REPO }}/${{ github.event.repository.name }}:${{ env.VERSION }} + provenance: false + + - name: Notice when job fails + if: failure() + uses: 8398a7/action-slack@v3.15.0 + with: + status: ${{job.status}} + fields: repo,workflow,job + author_name: Github Action Slack + + tagging: + needs: versioning_and_docker + runs-on: ubuntu-latest + env: + NEW_COMMIT_SHA: ${{ needs.versioning_and_docker.outputs.new_commit_sha }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ env.NEW_COMMIT_SHA }} + + - name: Configure git + run: | + git config --global user.email "${{ vars.GIT_EMAIL }}" + git config --global user.name "${{ vars.GIT_USERNAME }}" + + - name: Git tagging + run: | + git tag ${{ env.VERSION }} + git push origin ${{ env.VERSION }} + + - name: Notice when job fails + if: failure() + uses: 8398a7/action-slack@v3.15.0 + with: + status: ${{job.status}} + fields: repo,workflow,job + author_name: Github Action Slack + + notification: + needs: tagging + runs-on: ubuntu-latest + steps: + - name: Slack + if: always() + uses: 8398a7/action-slack@v3.15.0 + with: + status: ${{job.status}} + fields: repo,message,commit,author,action,ref,workflow,job + author_name: Github Action Slack diff --git a/apps/web/src/services/cost-explorer/components/AdvancedSettingsSetAdjustmentsOverlay.vue b/apps/web/src/services/cost-explorer/components/AdvancedSettingsSetAdjustmentsOverlay.vue index 1c57df7d39..d74f2c18e2 100644 --- a/apps/web/src/services/cost-explorer/components/AdvancedSettingsSetAdjustmentsOverlay.vue +++ b/apps/web/src/services/cost-explorer/components/AdvancedSettingsSetAdjustmentsOverlay.vue @@ -222,27 +222,27 @@ const handleSave = async () => { try { // CUD Adjustment Policy const deletedPolicyIds = await deleteAdjustmentPolicy(); - const policyPromises = formPolicies.value.map(async (policy, idx) => { + await formPolicies.value.reduce(async (promise, policy, idx) => { + await promise; if (policy.id.startsWith('rap-')) { return updateAdjustmentPolicy(policy, idx); } return createAdjustmentPolicy(policy, idx); - }); - await Promise.all(policyPromises); + }, Promise.resolve()); // CUD Adjustment await deleteAdjustment(deletedPolicyIds); - const adjustmentPromises = formPolicies.value.flatMap(async (policy) => { + await formPolicies.value.reduce(async (promise, policy) => { + await promise; const adjustments = formAdjustments.value.filter((adjustment) => adjustment.policyId === policy.id); - return adjustments.map(async (adjustment, idx) => { + return adjustments.reduce(async (adjPromise, adjustment, idx) => { + await adjPromise; if (adjustment.id.startsWith('ra-')) { return updateAdjustment(adjustment, idx); } return createAdjustment(adjustment, idx); - }); - }); - const resolvedAdjustments = await Promise.all(adjustmentPromises); - await Promise.all(resolvedAdjustments.flat()); + }, Promise.resolve()); + }, Promise.resolve()); showSuccessMessage(i18n.t('COST_EXPLORER.ADVANCED_SETTINGS.ALT_S_SAVE_COST_REPORT_ADJUSTMENTS'), ''); } catch (error) {