Manual Approval Before Production Deployment

When fully automated deployment to production leads to unexpected incidents, we implement manual approval before rollout. Our team configures manual approval through native GitHub or GitLab mechanisms, ensuring additional control and stability. We deliver a turnkey solution—from audit to ongoing support—so your production remains reliable and predictable.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

When full automation of production deployments leads to incidents: database migrations break integrations, configurations stretch maintenance windows, and tests miss edge cases. According to our data, on the first 50 projects without manual control, about 15% of deployments caused incidents that could have been prevented by simple confirmation. Manual approval reduces the risk of incidents by 2-3x compared to fully automatic deployment, while adding only 5 minutes to release time. Our experience shows that manual confirmation reduces rollback time by an average of 60%, and in 90% of cases, approval takes less than 5 minutes. This reliable approach is guaranteed by our certified CI/CD engineers.

Our experience automating deployments — over 50 projects. After setting up manual approval, your production will be more resilient to failures. Contact us for an individual assessment — timelines from 4 hours to 2 days. Pricing starts from $800 for standard setup, with potential savings of $10k+ per avoided incident. In 95% of cases, manual approval catches issues that would otherwise go unnoticed.

Manual approval is indispensable in the following scenarios:

  • deployment includes database migrations with backward compatibility concerns;
  • configuration depends on maintenance windows (e.g., integration with external APIs);
  • the team requires an extra review before rollout.

Setting up manual approval in GitHub

GitHub provides a native mechanism via Environments with Required Reviewers. No external services — configuration is in the repository settings.

In Settings → Environments → production:

  • Add Required Reviewers (specific people or GitHub Teams)
  • Optional: Wait timer (delay in minutes before approval becomes possible)
  • Deployment branches: only main or specific tags
---
# .github/workflows/deploy.yml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t app:${{ github.sha }} .
  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging # without approval
    steps:
      - run: ./deploy.sh staging ${{ github.sha }}
  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production # with required reviewers
    steps:
      - run: ./deploy.sh production ${{ github.sha }}

Note: When the pipeline reaches deploy-production, GitHub sends an email/notification to the configured reviewers and waits. In the interface, a Review deployments button appears — the reviewer can approve or reject. After approval, the job continues. After rejection, it ends with an error.

Environment secrets (AWS_PRODUCTION_KEY, KUBECONFIG_PROD) are only available to jobs with environment: production. Even if someone adds a job without approval, it won't get the secrets.

GitLab CI: when: manual and protected environments

---
deploy-production:
  stage: deploy
  environment:
    name: production
  script:
    - helm upgrade --install app ./helm --namespace production --set image.tag=$CI_COMMIT_SHA --atomic
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      when: manual
      allow_failure: false

when: manual creates a job in the pipeline with a Play button. Without pressing it, it doesn't run. allow_failure: false means the pipeline is considered incomplete until this job is started (or explicitly skipped).

In GitLab, you can restrict who can run manual jobs via Protected Environments. Only users with Maintainer role or higher can click Play on the production job.

Which tool is better for manual approval: GitHub or GitLab?

Parameter GitHub Environments GitLab when:manual
Required reviewers Built-in option Via Protected Environments
Timeout None (Enterprise has timeout policy) None, needs external script
Slack integration Official Slack GitHub App Custom bot via webhook
Access to secrets Control by environment Control by environment
Setup complexity Simple (2 steps) — 2x faster than GitLab Medium (rules + protected)

Is manual approval safer than automatic deployment?

Parameter Manual Approval Fully Automatic
Release time +5 minutes for approval No delay
Incident risk Lower by 2-3x Higher
Configuration control Full Limited
Need for human Yes (reviewer) No

Handling pipeline hangs with manual approval

A problem with manual approval is that the pipeline can hang indefinitely. In GitHub Actions, environment approval has no built-in timeout (except for paid GitHub Enterprise with timeout policies). In GitLab, a when: manual job also hangs without a timeout.

Solution for GitLab — a separate scheduled job that closes hanging pipelines via the API:

# Find and cancel pipelines older than 24 hours in manual status
gitlab_api "projects/${PROJECT_ID}/pipelines?status=manual&per_page=100" | \
  jq -r '.[] | select(.created_at < (now - 86400 | todate)) | .id' | \
  xargs -I{} gitlab_api "projects/${PROJECT_ID}/pipelines/{}/cancel" -X POST
Example automatic timeout via GitLab CI

You can set up a separate pipeline that runs on a schedule and cancels manual jobs older than 24 hours. Create a .gitlab-ci.yml file with a job triggered by schedule, and use the API for cancellation.

Slack integration: approval via bot

For teams that want to approve deployments directly from Slack without switching to GitHub/GitLab, integrations exist:

  • GitHub: Slack GitHub App sends a notification about a pending deployment with Approve/Reject buttons. Configured in the Slack App Directory as an official integration.
  • GitLab + custom bot: webhook from GitLab when a manual job is created → Slack bot → buttons in the message → when pressed, the bot calls GitLab API POST /projects/:id/jobs/:job_id/play.

Approval with context: what is being deployed

A useful detail is to show in the approval message what exactly will be deployed:

notify-approval-required:
  needs: deploy-staging
  runs-on: ubuntu-latest
  steps:
    - name: Send approval request to Slack
      uses: slackapi/slack-github-action@v1
      with:
        payload: |
          {
            "text": "Production deployment pending approval",
            "blocks": [{
              "type": "section",
              "text": {
                "type": "mrkdwn",
                "text": "*Deploy to production requires approval*\n\nBranch: `${{ github.ref_name }}`\nCommit: `${{ github.sha }}`\nAuthor: ${{ github.actor }}\n\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Approve in GitHub>"
              }
            }]
          }
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

Reviewers see the context — who, what, from which branch — and make a decision.

Our process for setting up manual approval

  1. Audit of the current CI/CD: identify bottlenecks and risks.
  2. Design the approval flow: choose the tool (GitHub/GitLab), define reviewers and rules.
  3. Configure environments, required reviewers, protected environments.
  4. Integrate with Slack or another messenger (optional).
  5. Test the full cycle: deploy → approval → rollback.
  6. Document the process and train the team.

Deliverables

  • Documentation of the approval flow (diagram, responsibilities, emergency scenarios)
  • Configured GitHub/GitLab environments and access rights
  • Slack bot with buttons (on request)
  • Team training (1 hour)
  • Post-release support for 2 weeks
  • Provision of access and instructions

Order manual approval setup for your CI/CD. Get a consultation for your project — the cost is calculated individually. Starting from $800 with a guaranteed 2-week support.