I am new to GitHub Action programming trying to write a workflow with "checks-action" that can initiate a check on the main page of the PR. The plan runs successfully and can output to script variable but seems "actions/github-script" facing permission issue posting the plan output to the PR. I tried different permission but still getting below error. Requesting help and advise.
If deploying without checks-action on a normal workflow, its able to post content with existing permission. Seems I am missing something with this process.
Run actions/github-script@v6
RequestError [HttpError]: Not Found
at /home/runner/work/_actions/actions/github-script/v6/dist/index.js:6803:21
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async eval (eval at callAsyncFunction (/home/runner/work/_actions/actions/github-script/v6/dist/index.js:15099:16), <anonymous>:4:28)
at async main (/home/runner/work/_actions/actions/github-script/v6/dist/index.js:15198:20) {
status: 404,
response: {
url: 'https://api.github.com/repos/My-Apps/devops-master/issues//comments',
status: 404,
headers: {
'access-control-allow-origin': '*',
'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset',
connection: 'close',
'content-encoding': 'gzip',
'content-security-policy': "default-src 'none'",
'content-type': 'application/json; charset=utf-8',
date: 'Tue, 04 Apr 2023 22:41:26 GMT',
'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin',
server: 'GitHub.com',
'strict-transport-security': 'max-age=31536000; includeSubdomains; preload',
'transfer-encoding': 'chunked',
vary: 'Accept-Encoding, Accept, X-Requested-With',
'x-content-type-options': 'nosniff',
'x-frame-options': 'deny',
'x-github-api-version-selected': '2022-11-28',
'x-github-media-type': 'github.v3',
'x-github-request-id': 'B740:1FCE:86030:113BD4:642CA796',
'x-ratelimit-limit': '15000',
'x-ratelimit-remaining': '14993',
'x-ratelimit-reset': '1680649234',
'x-ratelimit-resource': 'core',
'x-ratelimit-used': '7',
'x-xss-protection': '0'
},
data: {
message: 'Not Found',
documentation_url: 'https://docs.github.com/rest'
}
},
request: {
method: 'GET',
url: 'https://api.github.com/repos/My-Apps/devops-master/issues//comments',
headers: {
accept: 'application/vnd.github.-preview+json',
'user-agent': 'actions/github-script octokit-core.js/3.6.0 Node.js/16.16.0 (linux; x64)',
authorization: 'token [REDACTED]'
},
request: { agent: [Agent], hook: [Function: bound bound register] }
}
}
Error: Unhandled error: HttpError: Not Found
.github/workflows/tf_main.yml
name: Terraform WF
on:
pull_request:
types: [opened, edited, synchronize, reopened]
paths:
- 'accounts/global/**'
workflow_dispatch:
env:
action_assume_role: ${{ vars.ASSUME_ROLE }}
tf_version: 'latest'
tf_actions_working_dir: './accounts/global'
backend_s3_bucket: ${{ vars.BACKEND_BUCKET }}
backend_s3_region: ${{ vars.BACKEND_REGION }}
backend_encrypt_key: ${{ vars.BACKEND_KMS_KEY_ID }}
backend_tfstate_key: "${{ github.repository }}/accounts/global/global_state.tfstate"
permissions:
id-token: write
contents: read
pull-requests: write
actions: write
jobs:
terraform-fmt:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ env.tf_actions_working_dir }}
steps:
- uses: actions/checkout@v3
- uses: hashicorp/setup-terraform@v2
with:
terraform_version: ${{ env.tf_version }}
- name: terraform fmt
id: fmt
run: terraform fmt -check
continue-on-error: true
- name: Generate token
uses: tibdex/github-app-token@v1
id: get_installation_token
with:
app_id: ${{ secrets.APP_ID }}
private_key: ${{ secrets.PRIVATE_KEY }}
- uses: LouisBrunner/[email protected]
id: check
with:
sha: ${{ github.sha }}
token: ${{ steps.get_installation_token.outputs.token }}
name: terraform plan
status: in_progress
- name: Trigger Workflow
uses: actions/github-script@v6
with:
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'tf_deployment_plan.yml',
ref: '${{ github.head_ref }}',
inputs: {
"tf_actions_working_dir": "${{ env.tf_actions_working_dir }}",
"get_installation_token": "${{ steps.get_installation_token.outputs.token }}",
"action_assume_role": "${{ env.action_assume_role }}",
"backend_s3_bucket": "${{ env.backend_s3_bucket }}",
"backend_s3_region": "${{ env.backend_s3_region }}",
"backend_tfstate_key": "${{ env.backend_tfstate_key }}",
"backend_encrypt_key": "${{ env.backend_encrypt_key }}"
}
})
- uses: LouisBrunner/[email protected]
if: failure()
with:
sha: ${{ github.sha }}
token: ${{ steps.get_installation_token.outputs.token }}
name: terraform plan
conclusion: ${{ job.status }}
output: |
{"summary":"${{ steps.plan.outputs.summary }}"}
.github/workflows/tf_deployment_plan.yml
name: terraform plan
on:
workflow_dispatch:
inputs:
tf_actions_working_dir:
...
permissions:
id-token: write
contents: read
pull-requests: write
actions: write
issues: write
#checks: write
#contents: write
#deployments: write
#packages: write
#repository-projects: write
#security-events: write
#statuses: write
jobs:
terraform-plan:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ${{ github.event.inputs.tf_actions_working_dir }}
steps:
- uses: actions/checkout@v3
- uses: hashicorp/setup-terraform@v2
with:
terraform_version: ${{ env.tf_version }}
- uses: aws-actions/configure-aws-credentials@v2
with:
aws-region: ${{ github.event.inputs.backend_s3_region }}
role-to-assume: ${{ github.event.inputs.action_assume_role }}
mask-aws-account-id: false
- name: terraform init
id: init
run: terraform init
- name: terraform validate
id: validate
run: terraform validate -no-color
- name: terraform plan
id: plan
run: terraform plan -no-color
continue-on-error: true
- uses: actions/github-script@v6
# if: github.event_name == 'pull_request'
env:
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
with:
# github-token: ${{ secrets.GITHUB_TOKEN }}
# github-token: ${{ github.event.inputs.get_installation_token }}
script: |
...
#### Terraform Plan Output📖\`${{ steps.plan.outcome }}\`
<details><summary>Plan </summary>
\`\`\`\n
${process.env.PLAN}
\`\`\`
</details>
// 3. If we have a comment, update it, otherwise create a new one
if (botComment) {
github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: output
})
} else {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
}
- name: terraform plan status
if: steps.plan.outcome == 'failure'
run: exit 1
- uses: LouisBrunner/[email protected]
if: always()
with:
sha: ${{ github.sha }}
token: ${{ github.event.inputs.get_installation_token }}
name: terraform plan
conclusion: ${{ job.status }}
output: |
{"summary":"${{ steps.plan.outcome }}"}
Your issue is misuse of the context
in your script, as best as I can tell.
tf_deployment_plan is running under the workflow_dispatch context because that is the event that triggered it. Trying to access context.issue.number
will not provide a valid value, thus your 404 error trying to create the comment.
Give your provided workflows, what you need to do is add another input to tf_deployment_plan
that is the issue number, and pass that during your dispatch.
tf_main.yml
...
- name: Trigger Workflow
uses: actions/github-script@v6
with:
script: |
github.rest.actions.createWorkflowDispatch({
...
"backend_en crypt_key": "${{ env.backend_encrypt_key }}",
"issue": "${{ context.pull_request.number }}"
}
})
...
What will complicate the solution for tf_main is that you also have workflow_dispatch
as an event. For this to work for that case also, you will need to have an input under workflow_dispatch
and then add some additional code to check where you should get the issue number from.
tf_deployment_plan.yml
on:
workflow_dispatch:
inputs:
issue:
required: true
...
github.rest.issues.createComment({
issue_number: ${{ inputs.issue }},
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
...