Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: validate new issues GHA #2190

Merged
merged 8 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 23 additions & 25 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,39 @@ labels: 'investigating'
assignees: ''

---

<!--
NOTICE: GitHub is not a mechanism for receiving support under any agreement or SLA. If you require immediate assistance, please use official support channels.
-->
> **Note**
> Before you submit your issue, make sure that:
> - You're using the latest version of Salesforce CLI.
> - You've searched both open and closed issues for related posts.
> - You've used the `doctor` command to diagnose common issues.
> - You understand that GitHub Issues don't adhere to any agreement or SLA.
> - If you require immediate assistance, use official channels such as Salesforce Customer Support.

### Summary
<!-- Short summary of what's going on or to provide context -->

_Short summary of what is going on or to provide context_.

### Steps To Reproduce:
### Steps To Reproduce

**Repository to reproduce:** [dreamhouse-lwc](https://github.com/dreamhouseapp/dreamhouse-lwc)
> **IMPORTANT**
> Provide a repository that's configured to reproduce the issue. If you are unable to provide a repo, please explain why not. The more info we have from the start, the faster we can resolve your issue.
> We may close your issue if you don't include proper instructions.
>
> - Generate a project with `sf project generate` or fork [dreamhouse-lwc](https://github.com/trailheadapps/dreamhouse-lwc).
> - Provide detailed step-by-step instructions on how to reproduce the issue.

***NOTE:** If your issue is not reproducable by dreamhouse-lwc, i.e. requires specific metadata or files, we **require** a link to a simple Salesforce project repository with a script to setup a scratch org that reproduces your problem.*

1. This is step 1.
1. This is step 2. All steps should start with '1.'

### Expected result

_Describe what should have happened_.
<!-- Describe what should have happened -->

### Actual result

_Describe what actually happened_.
<!-- Describe what actually happened -->

### System Information
<!-- Which shell or terminal are you using? (bash, zsh, powershell 7, cmd.exe, etc) -->
<!-- Paste the **full** output of the `version --verbose --json` command for the CLI you're using (`sf` or `sfdx`) below -->

- Which shell/terminal are you using? (e.g. bash, zsh, powershell 5, powershell 7, cmd.exe, etc.)

- If you are using `sfdx`
- Run `sfdx version --verbose --json`
- If you are using `sf`
- Run `sf version --verbose --json`
- Paste the output here
```json
PASTE_VERSION_OUTPUT_HERE
```
### Additional information

_Feel free to attach a screenshot_.
<!-- Feel free to attach a screenshot -->
17 changes: 17 additions & 0 deletions .github/actions/validate-issue/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# Copyright (c) 2023, salesforce.com, inc.
# All rights reserved.
# Licensed under the BSD 3-Clause license.
# For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
#

name: "Salesforce CLI Validate Issues"
description: "Validate information provided in an new Github issue."
author: "Eric Willhoit"
inputs:
repo-token:
required: true
description: "Token taken from secrets env var"
runs:
using: "node16"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go higher since 16 is EOL in October.

I couldn't tell from the docs if there's a way to specify lts, but that would be best.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not supported yet 😑 actions/runner-images#7002 (comment)
I tried a work around there but it did not seem to work. Going to wait it out and hopefully they will add support

main: "index.js"
168 changes: 168 additions & 0 deletions .github/actions/validate-issue/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
const fs = require("fs");
const path = require("path");
const { getInput, setOutput, setFailed } = require("@actions/core");
const { context, getOctokit } = require("@actions/github");
const execSync = require("child_process").execSync;
const semver = require("semver");

async function run() {
try {
// Set this env var to true to test locally
// Example: GHA_VALIDATE_ISSUE_LOCAL=true node .github/actions/validate-issue/index.js
const local = process.env.GHA_VALIDATE_ISSUE_LOCAL;
const issue = local ? JSON.parse(getFile("./sample-context.json")) : context.payload.issue;

if (!issue) {
setFailed("github.context.payload.issue does not exist");
return;
}

// Temporary check to prevent this action from running on old issues
// This will prevent noise on tickets already being investigated
// This can be removed once the action has been running for a while
const creationDate = new Date(issue.created_at);
const cutoffDate = new Date("2023-06-11T00:00:00Z");
if (creationDate < cutoffDate) {
console.log("Issue was created before 6/11/2023, skipping");
return;
}
Comment on lines +20 to +28
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more thing, I added a date check to prevent this from running on old issues. Here is an example of the check failing: https://github.com/iowillhoit/gha-sandbox/actions/runs/5245104855/jobs/9472071608#step:5:8


const token = local ? process.env.GH_TOKEN : getInput("repo-token");

// Create a GitHub client
const octokit = getOctokit(token);

// Get owner and repo from context
if (local) process.env.GITHUB_REPOSITORY = "iowillhoit/gha-sandbox";
const owner = context.repo.owner;
const repo = context.repo.repo;
const issue_number = issue.number;

console.log("Issue URL:", issue.html_url);

const { body } = issue;
const { login: author } = issue.user;
const { data: comments } = await getAllComments();

// For version checks, we only care about comments from the author
const authorComments = comments.filter((comment) => comment.user.login === author);
// Build an array of the issue body and all of the comment bodies
const bodies = [body, ...authorComments.map((comment) => comment.body)];

const sfVersionRegex = /@salesforce\/cli\/([0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+.[0-9]+)?)/g;
const sfdxVersionRegex = /sfdx-cli\/([0-9]+.[0-9]+.[0-9]+(-[a-zA-Z0-9]+.[0-9]+)?)/g;
const pluginVersionsRegex = /pluginVersions|Plugin Version:/;

// Search all bodies and get an array of all versions found (first capture group)
const sfVersions = bodies.map((body) => [...body.matchAll(sfVersionRegex)].map((match) => match[1])).flat();
const sfdxVersions = bodies.map((body) => [...body.matchAll(sfdxVersionRegex)].map((match) => match[1])).flat();
// If we match pluginVersionRegex anywhere, we assume the user has provided the full --verbose output
const pluginVersionsIncluded = bodies.some((body) => body.match(pluginVersionsRegex));

console.log("sfVersions", sfVersions);
console.log("sfdxVersions", sfdxVersions);
console.log("pluginVersionsIncluded", pluginVersionsIncluded);

if ((sfVersions.length > 0 || sfdxVersions.length > 0) && pluginVersionsIncluded) {
// FUTURE TODO:
// - Check for bundled plugins that are user installed (user) or linked (link)
// - Could do a check to see if the users has a prerelease version installed
let valid = true;

if (sfVersions.length > 0) {
const sfLatest = getLatestVersion("@salesforce/cli");
const oneSatisfies = sfVersions.some((version) => semver.gte(version, sfLatest));

if (!oneSatisfies) {
const oldSf = getFile("./messages/old-cli.md", { THE_AUTHOR: author, USER_CLI: "sf", USER_VERSION: sfVersions.join("`, `"), LATEST_VERSION: sfLatest });
postComment(oldSf);
valid = false;
}
}
if (sfdxVersions.length > 0) {
// TODO: Eventually suggest using sf@v2, a new md template could be created
const sfdxLatest = getLatestVersion("sfdx-cli");
const oneSatisfies = sfdxVersions.some((version) => semver.gte(version, sfdxLatest));

if (!oneSatisfies) {
const oldSfdx = getFile("./messages/old-cli.md", { THE_AUTHOR: author, USER_CLI: "sfdx", USER_VERSION: sfdxVersions.join("`, `"), LATEST_VERSION: sfdxLatest });
postComment(oldSfdx);
valid = false;
}
}

if (valid) {
console.log("All information provided is valid!");
removeLabel("more information needed");
addLabel("investigating");
// This label will prevent the action from running again after version info has been confirmed
// Otherwise, this action will continue to trigger after every weekly release as `latest` is bumped
addLabel("validated");
} else {
console.log("Information provided is NOT valid");
addLabel("more information needed");
removeLabel("investigating");
}
} else {
console.log("Full version information was not provided");
const message = getFile("./messages/provide-version.md", { THE_AUTHOR: issue.user.login });
postComment(message);
addLabel("more information needed");
removeLabel("investigating");
}

// ---------
// FUNCTIONS
// ---------
async function getAllComments() {
return await octokit.rest.issues.listComments({ owner, repo, issue_number });
}

async function postComment(body) {
// Check that this comment has not been previously commented
if (comments.length) {
if (comments.some((comment) => comment.body === body)) {
console.log("Already commented");
return;
}
}

return await octokit.rest.issues.createComment({ owner, repo, issue_number, body });
}

async function addLabel(label) {
await octokit.rest.issues.addLabels({ owner, repo, issue_number, labels: [label] });
}

async function removeLabel(label) {
try {
await octokit.rest.issues.removeLabel({ owner, repo, issue_number, name: label });
} catch (error) {
if (error.status === 404) {
console.log(`Cannot remove label '${label}' since it was not applied`);
return;
}
throw error;
}
}

function getLatestVersion(plugin) {
const distTags = execSync(`npm view ${plugin} dist-tags --json`).toString();
return JSON.parse(distTags).latest;
}

function getFile(filename, replacements) {
let contents = fs.readFileSync(path.join(__dirname, filename), "utf8");

Object.entries(replacements || {}).map(([key, value]) => {
contents = contents.replaceAll(key, value);
});

return contents;
}
} catch (error) {
setFailed(error.message);
}
}

run();
9 changes: 9 additions & 0 deletions .github/actions/validate-issue/messages/old-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Hello @THE_AUTHOR :wave: None of the versions of `USER_CLI` you shared match the latest release.

Shared: `USER_VERSION`
Latest: `LATEST_VERSION`

Update to the latest version of Salesforce CLI ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_update_cli.htm)) and confirm that you're still seeing your issue.
You can also try the `rc` and `nightly` releases! ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli_rc.htm))

After updating, share the full output of `USER_CLI version --verbose --json`
13 changes: 13 additions & 0 deletions .github/actions/validate-issue/messages/provide-version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Hello @THE_AUTHOR :wave: It looks like you didn't include the full Salesforce CLI version information in your issue.
Please provide the output of `version --verbose --json` for the CLI you're using (`sf` or `sfdx`).

A few more things to check:

- Make sure you've provided detailed steps to reproduce your issue.
- A repository that clearly demonstrates the bug is ideal.
- Make sure you've installed the latest version of Salesforce CLI. ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_update_cli.htm))
- Better yet, try the `rc` or `nightly` versions. ([docs](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli_rc.htm))
- Try running the `doctor` command to diagnose common issues.
- Search GitHub for existing related issues.

Thank you!
70 changes: 70 additions & 0 deletions .github/actions/validate-issue/sample-context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"active_lock_reason": null,
"assignee": null,
"assignees": [],
"author_association": "OWNER",
"body": "@salesforce/cli/1.60.5 sfdx-cli/7.204.6 darwin-arm64 node-v18.15.0 pluginVersions",
"closed_at": null,
"comments": 0,
"comments_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/comments",
"created_at": "2023-06-06T21:03:32Z",
"events_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/events",
"html_url": "https://github.com/iowillhoit/gha-sandbox/issues/16",
"id": 1744609461,
"labels": [
{
"color": "FBCA04",
"default": false,
"description": "",
"id": 5589614072,
"name": "investigating",
"node_id": "LA_kwDOI7bi188AAAABTSq9-A",
"url": "https://api.github.com/repos/iowillhoit/gha-sandbox/labels/investigating"
}
],
"labels_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/labels{/name}",
"locked": false,
"milestone": null,
"node_id": "I_kwDOI7bi185n_KC1",
"number": 16,
"performed_via_github_app": null,
"reactions": {
"+1": 0,
"-1": 0,
"confused": 0,
"eyes": 0,
"heart": 0,
"hooray": 0,
"laugh": 0,
"rocket": 0,
"total_count": 0,
"url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/reactions"
},
"repository_url": "https://api.github.com/repos/iowillhoit/gha-sandbox",
"state": "open",
"state_reason": null,
"timeline_url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16/timeline",
"title": "Test",
"updated_at": "2023-06-06T21:49:50Z",
"url": "https://api.github.com/repos/iowillhoit/gha-sandbox/issues/16",
"user": {
"avatar_url": "https://avatars.githubusercontent.com/u/1715111?v=4",
"events_url": "https://api.github.com/users/iowillhoit/events{/privacy}",
"followers_url": "https://api.github.com/users/iowillhoit/followers",
"following_url": "https://api.github.com/users/iowillhoit/following{/other_user}",
"gists_url": "https://api.github.com/users/iowillhoit/gists{/gist_id}",
"gravatar_id": "",
"html_url": "https://github.com/iowillhoit",
"id": 1715111,
"login": "iowillhoit",
"node_id": "MDQ6VXNlcjE3MTUxMTE=",
"organizations_url": "https://api.github.com/users/iowillhoit/orgs",
"received_events_url": "https://api.github.com/users/iowillhoit/received_events",
"repos_url": "https://api.github.com/users/iowillhoit/repos",
"site_admin": false,
"starred_url": "https://api.github.com/users/iowillhoit/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/iowillhoit/subscriptions",
"type": "User",
"url": "https://api.github.com/users/iowillhoit"
}
}
37 changes: 37 additions & 0 deletions .github/workflows/issue-updated.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#
# Copyright (c) 2021, salesforce.com, inc.
# All rights reserved.
# Licensed under the BSD 3-Clause license.
# For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
#

name: "validate-updated-issue"
on:
issues:
types: [edited]
issue_comment:
types: [created, edited]

jobs:
validate-issue:
# Has label: 'more information needed'
# Does NOT have labels:
# - 'validated'
# - 'investigating'
# - 'feature'
# - 'owned by another team'
# - 'bug'
if: contains(github.event.issue.labels.*.name, 'more information needed') && !contains(github.event.issue.labels.*.name, 'validated') && !contains(github.event.issue.labels.*.name, 'investigating') && !contains(github.event.issue.labels.*.name, 'feature') && !contains(github.event.issue.labels.*.name, 'owned by another team') && !contains(github.event.issue.labels.*.name, 'bug')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3.0.0
- uses: actions/setup-node@v3
with:
node-version: lts/*
- name: Install dependencies
run: yarn install
- name: Validate issue
id: validate-issue
uses: ./.github/actions/validate-issue
with:
repo-token: ${{ secrets.GITHUB_TOKEN}}
Loading