peter-evans / slash-command-dispatch

A GitHub action that facilitates "ChatOps" by creating repository dispatch events for slash commands
MIT License
588 stars 53 forks source link

validate named arguments values ? #313

Closed DanyC97 closed 9 months ago

DanyC97 commented 10 months ago

👋 @peter-evans , thanks a bunch for the very useful action.

I was wondering if you came across the following use case , if not will you be willing to accept an enhancement ?

Using your action i have defined a couple of commands where a named argument is always required (mandatory). To take it a step further i also want the named argument to accept and dispatch commands only if the value provided is part of a known list. Otherwise, it should not fire a dispatch event and return a message back to inform the OP.

I have tried something different however things are not working, not sure (yet) why

the workflow dispatcher

name: ChatOps Command Dispatcher

on:
  issue_comment:
    types: [created]

permissions:
  contents: 'write' # to execute repository_dispatch
  id-token: 'write'
  pull-requests: 'write'

jobs:
  chatOps-Command-Dispatch:
    if: |
      github.event.issue.pull_request &&
      startsWith(github.event.comment.body, '/')
    runs-on: ubuntu-latest
    steps:
      - name: ChatOps Command Dispatcher
        uses: peter-evans/slash-command-dispatch@f996d7b7aae9059759ac55e978cff76d91853301 #tag=v3.0.2
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          issue-type: pull-request
          commands: |
            hello

the repository_dispatch workflow

name: 🔨 Debug workflow

on:
  repository_dispatch:
    types:
      - hello-command

jobs:
  dump_contexts_to_log:
    runs-on: ubuntu-latest
    steps:
      - name: Dump GitHub context
        env:
          GITHUB_CONTEXT: ${{ toJson(github) }}
        run: echo "$GITHUB_CONTEXT"

      - name: Output command and arguments
        run: |
          echo ${{ github.event.client_payload.slash_command.command }}
          echo ${{ github.event.client_payload.slash_command.args.all }}
          echo ${{ github.event.client_payload.slash_command.args.unnamed.all }}
          echo ${{ github.event.client_payload.slash_command.args.named.layer }}

  check-slash-commands:
    if: ${{ !contains(fromJson('["foo", "bar", "kilo", "alpha", "automation"]'), github.event.client_payload.slash_command.args.named.layer) }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write

    steps:
    - name: Print event
      run: |
        echo off
        echo '${{ toJson(github.event.client_payload.slash_command) }}'

    - name: Comment Reason failing the GHA workflow
      uses: peter-evans/create-or-update-comment@23ff15729ef2fc348714a3bb66d2f655ca9066f2 # tag=v3.1.0
      with:
        issue-number: ${{ github.event.client_payload.pull_request.number }}
        body: |
          The GHA workflow was skipped.

          The provided value for the 'layer' argument is invalid; accepted values are: `foo`/ `bar`/ `kilo`/ `alpha` or `automation`

    - name: Fail job in absence of valid slash command "layer" argument value
      run: |
        echo "The 'layer' argument value passed in the PR's comment is not valid, abort"
        exit 1

Since i didn't find any way to stop triggering any events nor , using advanced configuration, validate the named arg value it went the other side using a conditional expression.

Unfortunately the condition doesn't work as expected:

Not sure if i'm doing anything wrong ...

peter-evans commented 10 months ago

Hi @DanyC97

If you require validation for required arguments then it might be better to use workflow_dispatch, which has some validation built into the GitHub API. See here.

As for why your workflow isn't working, are you saying that this condition doesn't work?

if: ${{ !contains(fromJson('["foo", "bar", "kilo", "alpha", "automation"]'), github.event.client_payload.slash_command.args.named.layer) }}

It looks ok, but it difficult to say. Is your debug step showing the correct value for github.event.client_payload.slash_command.args.named.layer?

DanyC97 commented 9 months ago

thank you @peter-evans for coming back to me.

After a bit more digging found the reason why it was not working, it was all to do with toJson & fromJson.

In case others bump into it, the expression is

check-slash-commands:
  if: |
    contains(toJson(github.event.client_payload.slash_command.args.named), 'layer') &&
    !contains(toJson('["foo", "bar", "kilo", "alpha", "automation"]'), github.event.client_payload.slash_command.args.named.layer)
  runs-on: ubuntu-latest

silly user error 🤦‍♂️