Pause your GitHub Actions workflow and request manual approval from set approvers before continuing
Find a file
2026-04-23 14:05:35 +00:00
.gitignore create go sum at build-time with fresh hashes 2025-03-07 13:18:18 +05:30
action.yaml Replace mentions to github and forgejo for stackit git 2026-04-23 15:54:40 +02:00
approval.go use the repository-specific issue index instead of the global issue ID. 2026-04-23 12:51:58 +02:00
approval_test.go - Fixed Approver Expansion: Repaired the broken expandGroupFromUser function in approvers.go. It now correctly utilizes the Forgejo SDK to search for teams within an organization and expand them into individual users, while respecting the option to exclude the workflow initiator. 2026-04-22 15:28:23 +02:00
approvalstatus.go initial commit 2022-03-24 20:41:13 -04:00
approvers.go - Fixed Approver Expansion: Repaired the broken expandGroupFromUser function in approvers.go. It now correctly utilizes the Forgejo SDK to search for teams within an organization and expand them into individual users, while respecting the option to exclude the workflow initiator. 2026-04-22 15:28:23 +02:00
approvers_test.go Add ability to specify a team as an approver (#32) 2022-07-14 22:11:38 -04:00
constants.go Add configurable polling interval for GitHub API calls (#197) 2025-11-16 21:40:04 +05:30
CONTRIBUTING.md Replace mentions to github and forgejo for stackit git 2026-04-23 15:54:40 +02:00
Dockerfile - Fixed Approver Expansion: Repaired the broken expandGroupFromUser function in approvers.go. It now correctly utilizes the Forgejo SDK to search for teams within an organization and expand them into individual users, while respecting the option to exclude the workflow initiator. 2026-04-22 15:28:23 +02:00
go.mod - Fixed Approver Expansion: Repaired the broken expandGroupFromUser function in approvers.go. It now correctly utilizes the Forgejo SDK to search for teams within an organization and expand them into individual users, while respecting the option to exclude the workflow initiator. 2026-04-22 15:28:23 +02:00
LICENSE Initial commit 2022-03-24 20:43:53 -04:00
main.go Replace mentions to github and forgejo for stackit git 2026-04-23 15:54:40 +02:00
Makefile Updates for release 1.11.0 (#187) 2025-06-14 02:06:37 +05:30
README.md Replace mentions to github and forgejo for stackit git 2026-04-23 15:54:40 +02:00
Session.vim Create new release (#123) 2024-06-12 20:42:28 -04:00
workflow_dispatcher.md Replace mentions to github and forgejo for stackit git 2026-04-23 15:54:40 +02:00

Manual Workflow Approval

Pause a StackitGit Actions workflow and require manual approval from one or more approvers before continuing.

This is a very common feature for a deployment or release pipeline.

Note: This approval duration is subject to the broader 4 hours timeout for a workflow, as well as usage costs. So keep that in mind when figuring out how quickly an approver must respond. See limitations for more information.

*Note: A cheaper but less automatic solution using split jobs and workflow dispatcher can be seen in here

The way this action works is the following:

  1. Workflow comes to the manual-approval action.
  2. manual-approval will create an issue in the containing repository and assign it to the approvers.
  3. If and once all approvers respond with an approved keyword, the workflow will continue.
  4. If any of the approvers responds with a denied keyword, then the workflow will exit with a failed status.
  • Approval keywords - "approve", "approved", "lgtm", "yes"
  • Denied keywords - "deny", "denied", "no"

These are case insensitive with optional punctuation either a period or an exclamation mark.

In all cases, manual-approval will close the initial StackitGit issue.

Usage

steps:
  - uses: https://stackit.git.onstackit.cloud/actions/manual-approval@v1
    with:
      secret: ${{ github.TOKEN }}
      approvers: user1,user2,org-team1
      minimum-approvals: 1
      issue-title: "Deploying v1.3.5 to prod from staging"
      issue-body: "Please approve or deny the deployment of version v1.3.5."
      issue-body-file-path: relative/file_path/wrt/repo/root
      exclude-workflow-initiator-as-approver: false
      fail-on-denial: true
      additional-approved-words: ''
      additional-denied-words: ''
      polling-interval-seconds: 10
  • approvers is a comma-delimited list of all required approvers. An approver can either be a user or an org team. (Note: Required approvers must have the ability to be set as approvers in the repository. If you add an approver that doesn't have this permission then you would receive an HTTP/402 Validation Failed error when running this action)
  • minimum-approvals is an integer that sets the minimum number of approvals required to progress the workflow. Defaults to ALL approvers.
  • issue-title is a string that will be used as the title of the approval-issue.
  • issue-body is a string that will be added as comments on the approval-issue.
  • issue-body-file-path is a string that is the file path, this file's content will be added as comments on the approval-issue. If both issue-body and issue-body-file-path are given, then the file contents are considered for issue comments.
  • exclude-workflow-initiator-as-approver is a boolean that indicates if the workflow initiator (determined by the GITHUB_ACTOR environment variable) should be filtered from the final list of approvers. This is optional and defaults to false. Set this to true to prevent users in the approvers list from being able to self-approve workflows.
  • fail-on-denial is a boolean that indicates if the workflow should fail if any approver denies the approval. This is optional and defaults to true. Set this to false to allow the workflow to continue if any approver denies the approval.
  • additional-approved-words is a comma separated list of strings to expand the dictionary of words that indicate approval. This is optional and defaults to an empty string.
  • additional-denied-words is a comma separated list of strings to expand the dictionary of words that indicate denial. This is optional and defaults to an empty string.
  • polling-interval-seconds is an integer that sets the number of seconds to wait between polling the StackitGit API for approval status. This is optional and defaults to 10 seconds. Increase this value if you want to reduce API calls, or decrease it for faster response times.

Note

  1. If You are using issue-body-file-path then please make sure the file is reachable; for example, if the file is in your repo, then please checkout to your repo in the same job as the approval issue.
  2. When using issue-body, the content string is passed as an arguent which is limited by StackitGit at 10kb. For content >= 10kb, use files for passing the issue body.

Caution

When using a file please make sure that the file size remains under 125 KB (a safe limit, to stay under the threshold). If the file size is huge, then the file content will be broken into multiple chunks, each representing an issue comment. With this many API requests the API rate limit is exceeded, and the actions will be temporarily blocked, resulting in an error message like: 403 You have exceeded a secondary rate limit and have been temporarily blocked from content creation. Please retry your request again later.

5 MB is a crude estimate, as secondary rate limits apply to a user, so your user (usually the bot using an app token for authentication) will not be able to do anything for some time. Primary limits might still reset quickly, but secondary limits will need some cool-off time.

The file method works unless the file itself is so big that after breaking it into chunks of 65k characters, it exceeds the API limit.

Outputs

  • approval-status is a string that indicates the final status of the approval. This will be either approved or denied.

Creating Issues in a different repository

steps:
  - uses: https://stackit.git.onstackit.cloud/actions/manual-approval@v1
    with:
      secret: ${{ github.TOKEN }}
      approvers: user1,user2,org-team1
      minimum-approvals: 1
      issue-title: "Deploying v1.3.5 to prod from staging"
      issue-body: "Please approve or deny the deployment of version v1.3.5."
      exclude-workflow-initiator-as-approver: false
      additional-approved-words: ''
      additional-denied-words: ''
      target-repository: repository-name
      target-repository-owner: owner-id
  • If either of target-repository or target-repository-owner is missing or is an empty string, then the issue will be created in the same repository where this step is used.

Using Custom Words

StackitGit has a rich library of emojis, and these all work in additional approved words or denied words. Some values StackitGit will store in their text version - i.e. :shipit:. Other emojis, StackitGit will store in their Unicode emoji form, like . For a seamless experience, it is recommended that you add the custom words to a StackitGit comment, and then copy it back out of the comment into your actions configuration YAML.

Org team approver

If you want to have approvers set to an org team, then you need to take a different approach. The default StackitGit Actions automatic token does not have the necessary permissions to list out team members. If you would like to use this, then you need to generate a token from a StackitGit App with the correct set of permissions. Apart from this, the StackitGit app will also need the Issue: Read & Write role.

Create an Organization StackitGit App with read-only access to organization members. Once the app is created, add a repo secret with the app ID. In the StackitGit App settings, generate a private key and add that as a secret in the repo as well. You can get the app token by using the actions/create-github-app-token StackitGit Action:

Note: The StackitGit App tokens expire after 1 hour, which implies the duration for the approval cannot exceed 60 minutes, or the job will fail due to bad credentials. See docs.

jobs:
  myjob:
    runs-on: ubuntu-latest
    steps:
      - name: Generate token
        id: generate_token
        uses: actions/create-github-app-token@v2
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.APP_PRIVATE_KEY }}
      - name: Wait for approval
        uses: https://stackit.git.onstackit.cloud/actions/manual-approval@v1
        with:
          secret: ${{ steps.generate_token.outputs.token }}
          approvers: myteam
          minimum-approvals: 1

Timeout

If you'd like to force a timeout of your workflow pause, you can specify timeout-minutes at either the step level or the job level.

Note

The timeout-minutes option has been removed from the manual-approval inputs, as it did nothing and incorrectly assured users that they were in fact getting timeout behavior. Please use one of the below two approaches instead.

If you are currently using timeout-minutes as a manual-approval input, you may see a warning, but this will not break your action.

For instance, if you want your manual approval step to timeout after an hour, you could do the following:

jobs:
  approval:
    steps:
      - uses: https://stackit.git.onstackit.cloud/actions/manual-approval@v1
        timeout-minutes: 60
    # ...

or

jobs:
  approval:
    timeout-minutes: 10
    steps:
      - uses: https://stackit.git.onstackit.cloud/actions/manual-approval@v1

Limitations

  • While the workflow is paused, it will still continue to consume a concurrent job allocation out of the max concurrent job of 20.
  • A paused job is still running compute/instance/virtual machine and will continue to incur costs.
  • Expirations (also mentioned elsewhere in this document):
    • A job (including a paused job) will be failed after 4 hours, and a workflow will be failed after 35 days.
    • StackitGit App tokens expire after 1 hour, which implies the duration for the approval cannot exceed 60 minutes, or the job will fail due to bad credentials.