-
Notifications
You must be signed in to change notification settings - Fork 1
Add GitHub workflows #2
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Before you create this pull request | ||
|
|
||
| Thanks for your interest. This repository is a read-only mirror of a private repository and **we don't accept pull requests**. A workflow will close this PR automatically. | ||
|
|
||
| Do this instead: | ||
|
|
||
| - Cancel this PR. | ||
| - Report bugs, request features, or share feedback in the [Shopify dev community forums](https://community.shopify.dev/c/shopify-cli-libraries/14) | ||
|
|
||
| For more details see [CONTRIBUTING.md](https://github.com/Shopify/shopify-app-python/blob/main/CONTRIBUTING.md). |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,64 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| name: Close External PRs | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||
| pull_request_target: | ||||||||||||||||||||||||||||||||||||||||||||||
| types: [opened, reopened] | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||
| close-external-pr: | ||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||
| - name: Check if PR author is from Shopify | ||||||||||||||||||||||||||||||||||||||||||||||
| id: check-author | ||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/github-script@v7 | ||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||
| script: | | ||||||||||||||||||||||||||||||||||||||||||||||
| const author = context.payload.pull_request.user.login; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||
| // Check if the author is a member of the Shopify organization | ||||||||||||||||||||||||||||||||||||||||||||||
| await github.rest.orgs.checkMembershipForUser({ | ||||||||||||||||||||||||||||||||||||||||||||||
| org: 'Shopify', | ||||||||||||||||||||||||||||||||||||||||||||||
| username: author | ||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`${author} is a Shopify member`); | ||||||||||||||||||||||||||||||||||||||||||||||
| core.setOutput('is-shopify', 'true'); | ||||||||||||||||||||||||||||||||||||||||||||||
| } catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`${author} is not a Shopify member or the check failed: ${error.message}`); | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+31
|
||||||||||||||||||||||||||||||||||||||||||||||
| try { | |
| // Check if the author is a member of the Shopify organization | |
| await github.rest.orgs.checkMembershipForUser({ | |
| org: 'Shopify', | |
| username: author | |
| }); | |
| console.log(`${author} is a Shopify member`); | |
| core.setOutput('is-shopify', 'true'); | |
| } catch (error) { | |
| console.log(`${author} is not a Shopify member or the check failed: ${error.message}`); | |
| const authorAssociation = context.payload.pull_request.author_association; | |
| // Treat PR authors with OWNER or MEMBER association as internal Shopify contributors. | |
| const internalAssociations = ['OWNER', 'MEMBER']; | |
| if (internalAssociations.includes(authorAssociation)) { | |
| console.log(`${author} is considered an internal Shopify member (association: ${authorAssociation})`); | |
| core.setOutput('is-shopify', 'true'); | |
| } else { | |
| console.log(`${author} is not considered an internal Shopify member (association: ${authorAssociation})`); |
Copilot
AI
Jan 8, 2026
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.
The error handling catches all exceptions and treats them as "not a Shopify member", which could include legitimate API failures, rate limiting errors, or permission issues. This means that during an API outage or rate limit scenario, all PRs (including those from Shopify members) would be closed. Consider checking the error type and only treating 404 (Not Found) as "not a member", while handling other errors (403, 500, rate limits) differently or failing the workflow.
| console.log(`${author} is not a Shopify member or the check failed: ${error.message}`); | |
| core.setOutput('is-shopify', 'false'); | |
| // Only treat 404 (Not Found) as "not a Shopify member". | |
| // For other errors (e.g., 403, 429, 500), fail the workflow to | |
| // avoid incorrectly closing PRs during API issues. | |
| if (error && error.status === 404) { | |
| console.log(`${author} is not a Shopify member (404): ${error.message}`); | |
| core.setOutput('is-shopify', 'false'); | |
| } else { | |
| core.setFailed(`Failed to check Shopify membership for ${author}: ${error && error.message ? error.message : error}`); | |
| } |
Copilot
AI
Jan 8, 2026
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.
The reference to CONTRIBUTING.md should be formatted as a proper markdown link for consistency with the Pull Request Template, which uses a full URL. Consider changing this to a hyperlink format like: CONTRIBUTING.md or at minimum use a relative link format.
| For more details see CONTRIBUTING.md` | |
| For more details see [CONTRIBUTING.md](https://github.com/Shopify/shopify-app-python/blob/main/CONTRIBUTING.md)` |
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.
Using pull_request_target for external PRs is a known security risk as it runs with elevated permissions and access to secrets in the context of the base branch. While this workflow doesn't check out code, it's still important to ensure that no user-controlled input is used in potentially dangerous operations. The current implementation appears safe, but consider adding a comment documenting why pull_request_target is necessary here (to have write permissions for closing PRs) and confirming that no user input is used unsafely.