From ba1c1a75da15cf2977139fe2233f89b21cf357ec Mon Sep 17 00:00:00 2001 From: Artem Kladov Date: Thu, 27 Nov 2025 12:54:11 +0300 Subject: [PATCH 1/4] Implement workflow for deploying to production on PR merge to main. Signed-off-by: Artem Kladov --- .github/workflows/deploy-prod.yaml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deploy-prod.yaml b/.github/workflows/deploy-prod.yaml index 978c0ed..e967851 100644 --- a/.github/workflows/deploy-prod.yaml +++ b/.github/workflows/deploy-prod.yaml @@ -2,15 +2,14 @@ name: Deploy to production -# On every push to main branch. on: - push: - branches: - - 'main' + pull_request: + types: + - closed # Cancel in-progress jobs for the same tag/branch. concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.label.name }}-deploy + group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false permissions: @@ -20,12 +19,14 @@ permissions: jobs: deploy: runs-on: "regular" - if: ${{ github.event.label.name == 'deploy/test' || github.event.label.name == 'deploy/stage' }} + if: > + github.event.pull_request.merged == true && + github.event.pull_request.base.ref == 'main' steps: - name: Checkout code uses: actions/checkout@v4 with: - ref: ${{ github.event.pull_request.head.sha }} + ref: ${{ github.event.pull_request.merge_commit_sha || github.sha }} submodules: recursive fetch-depth: 0 From f4ea11a33e2b1ac7bc29a5c9e2b4593defcc0e46 Mon Sep 17 00:00:00 2001 From: Artem Kladov Date: Thu, 27 Nov 2025 13:09:57 +0300 Subject: [PATCH 2/4] Implement workflow for deploying to production on PR merge to main. Signed-off-by: Artem Kladov --- .github/workflows/deploy-dev.yaml | 23 ++++++++++++----------- .github/workflows/deploy-prod.yaml | 3 ++- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/deploy-dev.yaml b/.github/workflows/deploy-dev.yaml index ad481e2..6b7ac1d 100644 --- a/.github/workflows/deploy-dev.yaml +++ b/.github/workflows/deploy-dev.yaml @@ -9,7 +9,7 @@ on: # Cancel in-progress jobs for the same tag/branch. concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.label.name }}-deploy + group: ${{ github.workflow }}-${{ github.ref }}-${{ replace(github.event.label.name, '/', '-') }}-deploy cancel-in-progress: true permissions: @@ -21,7 +21,9 @@ permissions: jobs: deploy: runs-on: ubuntu-latest - if: ${{ github.event.label.name == 'deploy/test' || github.event.label.name == 'deploy/stage' }} + if: > + (github.event.label.name == 'deploy/test' || github.event.label.name == 'deploy/stage') + && startsWith(github.repository, 'deckhouse/') steps: - name: Checkout code uses: actions/checkout@v4 @@ -50,8 +52,8 @@ jobs: issue_number: context.payload.pull_request.number, body: `## 🚀 Deployment Started\n\n**Environment:** \`${env}\`\n\n_This comment will be updated with deployment status._` }); - core.setOutput('comment_id', comment.data.id); console.log(`Created comment: ${comment.data.id}`); + return comment.data.id; - name: Validate that Environment variable set run: | @@ -117,12 +119,12 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const env = '${{ steps.env.outputs.env }}'; - const commentId = ${{ steps.comment.outputs.comment_id }}; + const commentId = ${{ steps.comment.outputs.result }}; const repoName = context.repo.repo; const appName = repoName.startsWith('website-') ? repoName.replace(/^website-/, '') : repoName; const urlEn = `https://deckhouse.${env}.flant.com/products/${appName}/documentation/`; const urlRu = `https://deckhouse.ru.${env}.flant.com/products/${appName}/documentation/`; - + await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, @@ -138,25 +140,24 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const env = '${{ steps.env.outputs.env }}'; - const commentId = ${{ steps.comment.outputs.comment_id }}; - - // Get the job ID for the failed job + const commentId = ${{ steps.comment.outputs.result }}; + const jobs = await github.rest.actions.listJobsForWorkflowRun({ owner: context.repo.owner, repo: context.repo.repo, run_id: context.runId }); - + const job = jobs.data.jobs.find(j => j.name === 'deploy'); const jobId = job ? job.id : null; - + let logsUrl; if (jobId) { logsUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}/job/${jobId}`; } else { logsUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; } - + await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, diff --git a/.github/workflows/deploy-prod.yaml b/.github/workflows/deploy-prod.yaml index e967851..6c9465e 100644 --- a/.github/workflows/deploy-prod.yaml +++ b/.github/workflows/deploy-prod.yaml @@ -21,7 +21,8 @@ jobs: runs-on: "regular" if: > github.event.pull_request.merged == true && - github.event.pull_request.base.ref == 'main' + github.event.pull_request.base.ref == 'main' && + startsWith(github.repository, 'deckhouse/') steps: - name: Checkout code uses: actions/checkout@v4 From 90a736a8fd5fc24259c74fc86397f8ce2612bdcb Mon Sep 17 00:00:00 2001 From: Artem Kladov Date: Thu, 27 Nov 2025 13:17:00 +0300 Subject: [PATCH 3/4] Implement workflow for deploying to production on PR merge to main. Signed-off-by: Artem Kladov --- .github/workflows/deploy-dev.yaml | 26 +++++++++++++++++++++++--- .github/workflows/deploy-prod.yaml | 12 ++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-dev.yaml b/.github/workflows/deploy-dev.yaml index 6b7ac1d..e9ecacf 100644 --- a/.github/workflows/deploy-dev.yaml +++ b/.github/workflows/deploy-dev.yaml @@ -9,7 +9,7 @@ on: # Cancel in-progress jobs for the same tag/branch. concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-${{ replace(github.event.label.name, '/', '-') }}-deploy + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event.label.name }}-deploy cancel-in-progress: true permissions: @@ -97,6 +97,18 @@ jobs: password: ${{ steps.secrets.outputs.DECKHOUSE_DEV_REGISTRY_PASSWORD }} logout: false + - name: Validate deployment prerequisites + run: | + if [ -z "${{ steps.check_dev_registry.outputs.web_registry_path }}" ]; then + echo "::error::Dev registry credentials are missing. Cannot deploy." + exit 1 + fi + if [ -z "${{ steps.secrets.outputs.KUBECONFIG_BASE64_DEV }}" ]; then + echo "::error::Dev kubeconfig is missing. Cannot deploy." + exit 1 + fi + echo "✓ All prerequisites validated" + - name: Install werf uses: werf/actions/install@v2 @@ -113,13 +125,17 @@ jobs: werf converge - name: Update comment - deployment succeeded - if: success() + if: success() && steps.comment.outputs.result uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const env = '${{ steps.env.outputs.env }}'; const commentId = ${{ steps.comment.outputs.result }}; + if (!commentId) { + console.log('No comment ID available, skipping update'); + return; + } const repoName = context.repo.repo; const appName = repoName.startsWith('website-') ? repoName.replace(/^website-/, '') : repoName; const urlEn = `https://deckhouse.${env}.flant.com/products/${appName}/documentation/`; @@ -134,13 +150,17 @@ jobs: console.log(`Updated comment ${commentId} with success status`); - name: Update comment - deployment failed - if: failure() + if: failure() && steps.comment.outputs.result uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const env = '${{ steps.env.outputs.env }}'; const commentId = ${{ steps.comment.outputs.result }}; + if (!commentId) { + console.log('No comment ID available, skipping update'); + return; + } const jobs = await github.rest.actions.listJobsForWorkflowRun({ owner: context.repo.owner, diff --git a/.github/workflows/deploy-prod.yaml b/.github/workflows/deploy-prod.yaml index 6c9465e..4f93a28 100644 --- a/.github/workflows/deploy-prod.yaml +++ b/.github/workflows/deploy-prod.yaml @@ -92,6 +92,18 @@ jobs: password: ${{ steps.secrets.outputs.DECKHOUSE_REGISTRY_PASSWORD }} logout: false + - name: Validate deployment prerequisites + run: | + if [ -z "${{ steps.check_rw_registry.outputs.web_registry_path }}" ]; then + echo "::error::Production registry credentials are missing. Cannot deploy." + exit 1 + fi + if [ -z "${{ steps.secrets.outputs.KUBECONFIG_BASE64_PROD }}" ]; then + echo "::error::Production kubeconfig is missing. Cannot deploy." + exit 1 + fi + echo "✓ All prerequisites validated" + - name: Install werf uses: werf/actions/install@v2 From fb6ed065f1cf6ec0161f6e7b7bb917627ae534f0 Mon Sep 17 00:00:00 2001 From: Artem Kladov Date: Thu, 27 Nov 2025 13:29:12 +0300 Subject: [PATCH 4/4] Implement workflow for deploying to production on PR merge to main. Signed-off-by: Artem Kladov --- .github/workflows/deploy-dev.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-dev.yaml b/.github/workflows/deploy-dev.yaml index e9ecacf..cf0356d 100644 --- a/.github/workflows/deploy-dev.yaml +++ b/.github/workflows/deploy-dev.yaml @@ -1,6 +1,6 @@ # WF for deploying to test/stage envs on PR label 'deploy/test' or 'deploy/stage' -name: Deploy on label +name: Deploy to dev environments on: pull_request_target: @@ -20,6 +20,7 @@ permissions: jobs: deploy: + name: Deploy to ${{ github.event.label.name }} runs-on: ubuntu-latest if: > (github.event.label.name == 'deploy/test' || github.event.label.name == 'deploy/stage')