-
Notifications
You must be signed in to change notification settings - Fork 78
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
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
48a124a
feat: validate new issues GHA
iowillhoit 4eab05f
edit bug_report.md
jshackell-sfdc f52c621
edit old-cli.md
jshackell-sfdc 3b6c2bf
edit provide-version.md
jshackell-sfdc a271df2
Update old-cli.md
jshackell-sfdc 27e31ec
Update bug_report.md
jshackell-sfdc cba36bd
chore: add/remove labels, supports comments
iowillhoit 0367c8c
add date check
iowillhoit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
main: "index.js" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
13
.github/actions/validate-issue/messages/provide-version.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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