diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 6a7ba05..1e21426 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -23,6 +23,53 @@ env: REGISTRY_URL: ghcr.io/${{ github.repository_owner }} jobs: + deploy-config: + name: Check Deploy Configuration + runs-on: ubuntu-latest + outputs: + staging_ready: ${{ steps.check.outputs.staging_ready }} + production_ready: ${{ steps.check.outputs.production_ready }} + + steps: + - name: Check required deploy secrets + id: check + env: + TARGET_ENV: ${{ inputs.environment }} + STAGING_HOST: ${{ secrets.STAGING_HOST }} + STAGING_USER: ${{ secrets.STAGING_USER }} + STAGING_SSH_KEY: ${{ secrets.STAGING_SSH_KEY }} + STAGING_URL: ${{ secrets.STAGING_URL }} + STAGING_API_URL: ${{ secrets.STAGING_API_URL }} + PRODUCTION_HOST: ${{ secrets.PRODUCTION_HOST }} + PRODUCTION_USER: ${{ secrets.PRODUCTION_USER }} + PRODUCTION_SSH_KEY: ${{ secrets.PRODUCTION_SSH_KEY }} + PRODUCTION_URL: ${{ secrets.PRODUCTION_URL }} + PRODUCTION_API_URL: ${{ secrets.PRODUCTION_API_URL }} + run: | + STAGING_READY=false + PRODUCTION_READY=false + + if [ -n "$STAGING_HOST" ] && [ -n "$STAGING_USER" ] && [ -n "$STAGING_SSH_KEY" ] && [ -n "$STAGING_URL" ] && [ -n "$STAGING_API_URL" ]; then + STAGING_READY=true + fi + + if [ -n "$PRODUCTION_HOST" ] && [ -n "$PRODUCTION_USER" ] && [ -n "$PRODUCTION_SSH_KEY" ] && [ -n "$PRODUCTION_URL" ] && [ -n "$PRODUCTION_API_URL" ]; then + PRODUCTION_READY=true + fi + + echo "staging_ready=$STAGING_READY" >> "$GITHUB_OUTPUT" + echo "production_ready=$PRODUCTION_READY" >> "$GITHUB_OUTPUT" + + if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ "$TARGET_ENV" = "staging" ] && [ "$STAGING_READY" != "true" ]; then + echo "Missing required staging deploy secrets; configure STAGING_HOST, STAGING_USER, STAGING_SSH_KEY, STAGING_URL, and STAGING_API_URL." + exit 1 + fi + + if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ "$TARGET_ENV" = "production" ] && [ "$PRODUCTION_READY" != "true" ]; then + echo "Missing required production deploy secrets; configure PRODUCTION_HOST, PRODUCTION_USER, PRODUCTION_SSH_KEY, PRODUCTION_URL, and PRODUCTION_API_URL." + exit 1 + fi + build-api: name: Build API Image runs-on: ubuntu-latest @@ -154,11 +201,14 @@ jobs: deploy-staging: name: Deploy to Staging - needs: [build-api, build-web, build-ai] + needs: [deploy-config, build-api, build-web, build-ai] if: >- - github.ref == 'refs/heads/develop' || - (github.event_name == 'push' && github.ref == 'refs/heads/master') || - (github.event_name == 'workflow_dispatch' && inputs.environment == 'staging') + needs.deploy-config.outputs.staging_ready == 'true' && + ( + github.ref == 'refs/heads/develop' || + (github.event_name == 'push' && github.ref == 'refs/heads/master') || + (github.event_name == 'workflow_dispatch' && inputs.environment == 'staging') + ) runs-on: ubuntu-latest environment: staging @@ -394,8 +444,11 @@ jobs: rollback-staging: name: Rollback Staging - needs: [deploy-staging, smoke-test-staging] - if: failure() + needs: [deploy-config, deploy-staging, smoke-test-staging] + if: >- + always() && + needs.deploy-config.outputs.staging_ready == 'true' && + (needs.deploy-staging.result == 'failure' || needs.smoke-test-staging.result == 'failure') runs-on: ubuntu-latest environment: staging @@ -462,8 +515,11 @@ jobs: deploy-production: name: Deploy to Production - needs: [build-api, build-web, build-ai] - if: inputs.environment == 'production' + needs: [deploy-config, build-api, build-web, build-ai] + if: >- + github.event_name == 'workflow_dispatch' && + inputs.environment == 'production' && + needs.deploy-config.outputs.production_ready == 'true' runs-on: ubuntu-latest environment: production @@ -654,8 +710,11 @@ jobs: rollback-production: name: Rollback Production - needs: [deploy-production, smoke-test-production] - if: failure() + needs: [deploy-config, deploy-production, smoke-test-production] + if: >- + always() && + needs.deploy-config.outputs.production_ready == 'true' && + (needs.deploy-production.result == 'failure' || needs.smoke-test-production.result == 'failure') runs-on: ubuntu-latest environment: production