Repository: pulumi/actions
Pull request #679 (2022-07-07 20:51:59)

Only "Comment-On-PRs" when running in a PR context
v3.18.0 introduced a bug where Actions that supplied `comment-on-true: true` would panic when not running within the context of a PR (_i.e._ `event type == pull_request`). This resulted in panics for users with `pulumi@v3` in their workflows, which is fairly common as it's what the docs suggest to do.

This PR adds a guard to check if we're in a PR context before issuing comments.

Fixes https://github.com/pulumi/actions/issues/677 which is a P1.

RobbieMcKinstry: Ahhh welp, this change didn' fix my repro... that's very sad.
The PR is missing a regression test but God darn I really thought this was the root of the issue.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1814dbd..789250a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,9 @@
 
 - revert runtime requirement from node 16 to node 12
 
+- bug: Resolves a panic when using `comment-on-pr: true` when not running on an
+  event of type `pull_request`.
+  [#679](https://github.com/pulumi/actions/issues/679)
 
 ---
 
diff --git a/src/config.ts b/src/config.ts
index d9c4a0b..41c1c5e 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,4 +1,5 @@
 import { getInput } from '@actions/core';
+import { context } from '@actions/github';
 import * as rt from 'runtypes';
 import { parseArray, parseBoolean, parseNumber } from './libs/utils';
 
@@ -34,6 +35,8 @@ export const config = rt
     workDir: rt.String,
     commentOnPr: rt.Boolean,
     options: options,
+    // Information inferred from the environment that must be present
+    isPullRequest: rt.Boolean,
   })
   .And(
     rt.Partial({
@@ -59,6 +62,7 @@ export async function makeConfig(): Promise<Config> {
     commentOnPr: parseBoolean(getInput('comment-on-pr')),
     upsert: parseBoolean(getInput('upsert')),
     refresh: parseBoolean(getInput('refresh')),
+    isPullRequest: context?.payload?.pull_request !== undefined,
     options: {
       parallel: parseNumber(getInput('parallel')),
       message: getInput('message'),
diff --git a/src/main.ts b/src/main.ts
index e5e1555..8aa021b 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -91,7 +91,7 @@ const main = async () => {
     }
   }
 
-  if (config.commentOnPr) {
+  if (config.commentOnPr && config.isPullRequest) {
     core.debug(`Commenting on pull request`);
     invariant(config.githubToken, 'github-token is missing.');
     handlePullRequestMessage(config, output);


Test patch:
diff --git a/src/__tests__/config.test.ts b/src/__tests__/config.test.ts
index 87ce5fc..daad763 100644
--- a/src/__tests__/config.test.ts
+++ b/src/__tests__/config.test.ts
@@ -21,6 +21,9 @@ describe('config.ts', () => {
         return config[name];
       }),
     }));
+    jest.mock('@actions/github', () => ({
+      context: {},
+    }));
 
     const { makeConfig } = require('../config');
 
@@ -32,6 +35,7 @@ describe('config.ts', () => {
         "command": "up",
         "commentOnPr": false,
         "githubToken": "n/a",
+        "isPullRequest": false,
         "options": Object {
           "color": undefined,
           "diff": undefined,
@@ -63,6 +67,9 @@ describe('config.ts', () => {
         return config[name];
       }),
     }));
+    jest.mock('@actions/github', () => ({
+      context: {},
+    }));
 
     const { makeConfig } = require('../config');
 
@@ -89,6 +96,60 @@ describe('config.ts', () => {
         "command": "up",
         "commentOnPr": true,
         "githubToken": "n/a",
+        "isPullRequest": false,
+        "options": Object {
+          "color": undefined,
+          "diff": undefined,
+          "editCommentOnPr": undefined,
+          "expectNoChanges": undefined,
+          "message": undefined,
+          "parallel": undefined,
+          "policyPackConfigs": undefined,
+          "policyPacks": undefined,
+          "replace": undefined,
+          "target": undefined,
+          "targetDependents": undefined,
+          "userAgent": "pulumi/actions@v3",
+        },
+        "refresh": undefined,
+        "secretsProvider": undefined,
+        "stackName": "dev",
+        "upsert": undefined,
+        "workDir": "./",
+      }
+    `);
+  });
+  it('should determine when in a PR', async () => {
+    const config = {
+      ...defaultConfig,
+      'comment-on-pr': 'false',
+    };
+    jest.mock('@actions/core', () => ({
+      getInput: jest.fn((name: string) => {
+        return config[name];
+      }),
+    }));
+    jest.mock('@actions/github', () => ({
+      context: {
+        payload: {
+          pull_request: {
+            number: 5678,
+          },
+        },
+      },
+    }));
+
+    const { makeConfig } = require('../config');
+
+    const c = await makeConfig();
+    expect(c).toBeTruthy();
+    expect(c).toMatchInlineSnapshot(`
+      Object {
+        "cloudUrl": "file://~",
+        "command": "up",
+        "commentOnPr": false,
+        "githubToken": "n/a",
+        "isPullRequest": true,
         "options": Object {
           "color": undefined,
           "diff": undefined,