This message was deleted.
# atlantis-community
s
This message was deleted.
l
Here's a snapshot of our configuration :
Copy code
version: 3
delete_source_branch_on_merge: true
automerge: false
projects:

- name: sdbx-deployment
  # execution_order_group: 1 => raised an error
  branch: /hotfix/
  dir: infra
  workspace: staging
  autoplan:
    when_modified: ["*.tf", "./values/sdbx-sre/*.tfvars", "./infra/values/sdbx-sre/*.tfvars"]
    enabled: true
  apply_requirements: [mergeable, approved]
  workflow: tf-deployment

workflows:
  tf-deployment:
    plan:
      steps:
      - init
      - run: terraform workspace select $WORKSPACE || terraform workspace new $WORKSPACE
      - env:
          name: AWS_ACCOUNT
          command: 'echo $WORKSPACE | cut -d "_" -f4'
      - plan:
          extra_args:
          - "-var-file=values/$AWS_ACCOUNT/$WORKSPACE.tfvars"
    apply:
      steps:
      - run: terraform workspace select $WORKSPACE
      - apply
o
> Our aim is to enable
atlantis apply
on a hotfix branch without the need for a PR approval. at my org i did solve this problem differently -- we have a custom github action workflow that reacts to
/approve
comment and then the technical user account (bot) comes in and approves the pr. the workflow accepts a github team, so basically only sre can use
/approve
.
👍 1
it's simple, efficient and works all the time. i can share some snippets of it if you want.
👍 1
l
Hello @oponomarov-tu, thanks for your answer and for giving me this workaround, we'll try it on our own. As you suggested, I wouldn't say no to a few snippets to give me a starting base. Thanks for your time and wishing you a good day.
o
@Loïc Petit, sorry for taking this so long, i was away! i store this in an internal repo with reusable github workflows: slash-commands.yaml:
Copy code
---
name: slash command dispatcher

on:
  workflow_call:
    secrets:
      gh_token:
        required: true

jobs:
  command:
    runs-on: ubuntu-latest
    steps:
      - name: slash command dispatch pull-request
        if: ${{ github.event.issue.pull_request }}
        uses: peter-evans/slash-command-dispatch@v3
        with:
          token: ${{ secrets.gh_token }}
          commands: |
            approve
          static-args: |
            author=${{ github.actor }}
            pull_request=true
            pull_request_number=${{ github.event.issue.number }}
slash-on-approve.yaml:
Copy code
---
name: slash command on approve

on:
  workflow_call:
    inputs:
      allowed_team:
        description: "The team name that is permitted to execute the `/approve` command. This team should belong to the specified organization."
        required: true
        type: string
      approver:
        description: "The GitHub user or bot that will be marked as the approver for certain actions within this workflow. Defaults to '<redacted>-ci-bot'."
        required: false
        type: string
        default: "<redacted>-ci-bot"
      organization:
        description: "The name of the GitHub organization in which the allowed team is situated. Defaults to '<your org name>'."
        required: false
        type: string
        default: "<your org name>"
    secrets:
      gh_token:
        description: "The GitHub token used for authentication and performing privileged actions (review / approve) within this workflow. Make sure this token has appropriate permissions."
        required: true

jobs:
  command:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v6
        with:
          github-token: ${{ secrets.gh_token }}
          debug: true
          script: |
            const pull_request = '${{ github.event.client_payload.slash_command.args.named.pull_request }}'
            const pull_request_number = '${{ github.event.client_payload.slash_command.args.named.pull_request_number }}'
            const author = '${{ github.event.client_payload.slash_command.args.named.author }}'
            const approver = '${{ inputs.approver }}'
            const allowed_teams = ['${{ inputs.allowed_team }}']

            // Check if author belongs to any of the allowed teams
            var is_allowed = false;
            for (const team of allowed_teams) {
              try {
                const { data: membership } = await github.rest.teams.getMembershipForUserInOrg({
                  org: '${{ inputs.organization }}',
                  team_slug: team,
                  username: author
                });
                if (membership.state === "active") {
                  is_allowed = true;
                  break;
                }
              } catch (error) {
                console.log(`User ${author} is not a member of team ${team}`);
              }
            }

            if (!is_allowed) {
              github.rest.issues.createComment({
                issue_number: pull_request_number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: `Error: You must be a member of one of the following teams to use the \`/approve\` command: ${allowed_teams.join(', ')}.`
              });
              return;
            }

            const {data: thepull} = await github.rest.pulls.get({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: pull_request_number
            })

            const output = `Emergency pull-request approval. Approved by: \`${approver}\``;

            const {data: reviewers} = await github.rest.pulls.listRequestedReviewers({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: pull_request_number
            });

            const {data: reviews} = await github.rest.pulls.listReviews({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: pull_request_number
            });

            var is_approved = false;
            var is_requested_for_review = false;

            for (const aReview of reviews) {
              if(aReview.user.login == approver && aReview.state == 'APPROVED') {
                is_approved = true;
                break;
              }
            }

            for (const aUser of reviewers.users) {
              if (aUser.login == approver) {
                is_requested_for_review = true;
                break;
              }
            }

            if (!is_approved || is_requested_for_review) {
              await github.rest.pulls.createReview({
                owner: context.repo.owner,
                repo: context.repo.repo,
                pull_number: pull_request_number,
                event: "APPROVE"
              });

              github.rest.issues.createComment({
                issue_number: pull_request_number,
                owner: context.repo.owner,
                repo: context.repo.repo,
                body: output
              });
            }
then in the terraform repo just call the workflows: 1:
Copy code
---
name: chatops

on:
  issue_comment:
    types:
      - created

permissions:
  issues: write
  pull-requests: write

jobs:
  slash-command-dispatcher:
    uses: <org name>/github-actions/.github/workflows/slash-commands.yaml@master
    secrets:
      gh_token: ${{ secrets.<pat for the ci bot that can approve the pr> }}
2:
Copy code
---
name: slash command on approve

on:
  repository_dispatch:
    types:
      - approve-command

permissions:
  issues: write
  pull-requests: write

jobs:
  slash-command-dispatcher:
    uses: <org name>/github-actions/.github/workflows/slash-on-approve.yaml@master
    with:
      allowed_team: 'team-name-that-can-/approve'
    secrets:
      gh_token: ${{ secrets.<pat for the ci bot that can approve the pr> }}
l
Hey @oponomarov-tu thank you for your answer, we manage to do it on our side with the gh cli 🙂 We're doing something similar, we've added a few conditions: • Member of an OnCall team • OnCall periode verification • Allow an explicit repository list • Only on hotfixes branches. • Send push notifications on slack Thanks for the idea, it seems to solve our problem.
👍 1