-
Notifications
You must be signed in to change notification settings - Fork 794
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #925 from 1Password/jh/approve-merge
Set up application approval workflow and logic
- Loading branch information
Showing
6 changed files
with
321 additions
and
11 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: Approve application | ||
|
||
on: | ||
issues: | ||
types: [labeled] | ||
|
||
jobs: | ||
check: | ||
runs-on: ubuntu-latest | ||
outputs: | ||
is_approved: ${{ steps.check_label.outputs.is_approved }} | ||
approver_id: ${{ steps.check_label.outputs.approver_id }} | ||
approver_username: ${{ steps.check_label.outputs.approver_username }} | ||
steps: | ||
- id: check_label | ||
name: "Check if label is 'status: approved'" | ||
run: | | ||
echo "is_approved=$(echo ${{ github.event.label.name == 'status: approved' }})" >> $GITHUB_OUTPUT | ||
echo "approver_id=${{ github.event.sender.id }}" >> $GITHUB_OUTPUT | ||
echo "approver_username=${{ github.event.sender.login }}" >> $GITHUB_OUTPUT | ||
approve: | ||
needs: check | ||
runs-on: ubuntu-latest | ||
if: needs.check.outputs.is_approved == 'true' | ||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Fetch processor | ||
uses: dsaltares/fetch-gh-release-asset@1.1.1 | ||
with: | ||
file: "processor" | ||
target: "./processor" | ||
|
||
- name: Automated application approval | ||
run: | | ||
chmod +x ./processor | ||
./processor approve | ||
env: | ||
APPROVER_ID: ${{ needs.check.outputs.approver_id }} | ||
APPROVER_USERNAME: ${{ needs.check.outputs.approver_username }} | ||
OP_BOT_PAT: ${{ secrets.OP_BOT_PAT }} | ||
ISSUE_NUMBER: ${{ github.event.issue.number }} | ||
REPOSITORY_OWNER: ${{ github.repository_owner }} | ||
REPOSITORY_NAME: ${{ github.event.repository.name }} |
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,103 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"log" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
type Approver struct { | ||
gitHub GitHub | ||
application Application | ||
} | ||
|
||
func (a *Approver) Approve() { | ||
a.gitHub = GitHub{} | ||
a.application = Application{} | ||
|
||
if err := a.application.SetApprover(); err != nil { | ||
a.printErrorAndExit(err) | ||
} | ||
|
||
if err := a.gitHub.Init(); err != nil { | ||
a.printErrorAndExit(err) | ||
} | ||
|
||
if *a.gitHub.Issue.State == "closed" { | ||
a.printErrorAndExit(errors.New("script run on closed issue")) | ||
} | ||
|
||
if !a.gitHub.IssueHasLabel(LabelStatusApproved) { | ||
a.printErrorAndExit( | ||
fmt.Errorf("script run on issue that does not have required '%s' label", LabelStatusApproved), | ||
) | ||
} | ||
|
||
a.application.Parse(a.gitHub.Issue) | ||
|
||
if !a.application.IsValid() { | ||
a.printErrorAndExit( | ||
fmt.Errorf("script run on issue with invalid application data:\n\n%s", a.renderProblems()), | ||
) | ||
} | ||
|
||
// The reviewer may remove this label themselves, but | ||
// let's double check and remove it if they haven't | ||
if a.gitHub.IssueHasLabel(LabelStatusReviewing) { | ||
if err := a.gitHub.RemoveIssueLabel(LabelStatusReviewing); err != nil { | ||
a.printErrorAndExit( | ||
fmt.Errorf("could not remove issue label '%s': %s", LabelStatusReviewing, err.Error()), | ||
) | ||
} | ||
} | ||
|
||
if err := a.gitHub.CommitNewFile( | ||
filepath.Join("data", a.application.FileName()), | ||
a.application.GetData(), | ||
fmt.Sprintf("Added \"%s\" to program", a.application.Project.Name), | ||
); err != nil { | ||
a.printErrorAndExit( | ||
fmt.Errorf("could not create commit: %s", err.Error()), | ||
) | ||
} | ||
|
||
if err := a.gitHub.CreateIssueComment(a.getApprovalMessage()); err != nil { | ||
a.printErrorAndExit( | ||
fmt.Errorf("could not create issue comment: %s", err.Error()), | ||
) | ||
} | ||
|
||
if err := a.gitHub.CloseIssue(); err != nil { | ||
a.printErrorAndExit( | ||
fmt.Errorf("could not close issue: %s", err.Error()), | ||
) | ||
} | ||
} | ||
|
||
func (a *Approver) printErrorAndExit(err error) { | ||
log.Fatalf("Error approving application: %s\n", err.Error()) | ||
} | ||
|
||
func (a *Approver) renderProblems() string { | ||
var problemStrings []string | ||
|
||
for _, err := range a.application.Problems { | ||
problemStrings = append(problemStrings, fmt.Sprintf("- %s", err.Error())) | ||
} | ||
|
||
return strings.Join(problemStrings, "\n") | ||
} | ||
|
||
func (a *Approver) getApprovalMessage() string { | ||
return strings.TrimSpace(fmt.Sprintf(`### 🎉 Your application has been approved | ||
Congratulations, @%s has approved your application! A promotion will be applied to your 1Password account shortly. | ||
To lower the risk of lockout, [assign at least one other person to help with account recovery](https://support.1password.com/team-recovery-plan/) in case access for a particular team member is ever lost. You may add additional core contributors as you see fit. | ||
Finally, we’d love to hear more about your experience using 1Password in your development workflows! Feel free to join us over on the [1Password Developers Slack](https://join.slack.com/t/1password-devs/shared_invite/zt-15k6lhima-GRb5Ga~fo7mjS9xPzDaF2A) workspace. | ||
Welcome to the program and happy coding! 🧑💻`, a.application.ApproverUsername)) | ||
} |
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,60 @@ | ||
{ | ||
"id": 1801650328, | ||
"number": 6, | ||
"state": "open", | ||
"locked": false, | ||
"title": "Application for TestDB", | ||
"body": "### Account URL\n\ntestdb.1password.com\n\n### Non-commercial confirmation\n\n- [X] No, this account won't be used for commercial activity\n\n### Team application\n\n- [ ] Yes, this application is for a team\n\n### Event application\n\n- [ ] Yes, this application is for an event\n\n### Project name\n\nTestDB\n\n### Short description\n\nTestDB is a free and open source, community-based forum software project.\n\n### Number of team members/core contributors\n\n1\n\n### Homepage URL\n\nhttps://github.com/wendyappleed/test-db\n\n### Repository URL\n\nhttps://github.com/wendyappleed/test-db\n\n### License type\n\nMIT\n\n### License URL\n\nhttps://github.com/wendyappleed/test-db/blob/main/LICENSE.md\n\n### Age confirmation\n\n- [X] Yes, this project is at least 30 days old\n\n### Name\n\nWendy Appleseed\n\n### Email\n\nwendyappleseed@example.com\n\n### Project role\n\nCore Maintainer\n\n### Profile or website\n\nhttps://github.com/wendyappleseed/\n\n### Can we contact you?\n\n- [X] Yes, you may contact me\n\n### Additional comments\n\nThank you!", | ||
"user": { | ||
"login": "wendyappleseed", | ||
"id": 38230737, | ||
"node_id": "MDQ6VXNlcjYzOTIwNDk=", | ||
"avatar_url": "https://avatars.githubusercontent.com/u/38230737?v=4", | ||
"html_url": "https://github.com/wendyappleseed", | ||
"gravatar_id": "", | ||
"type": "User", | ||
"site_admin": false, | ||
"url": "https://api.github.com/users/wendyappleseed", | ||
"events_url": "https://api.github.com/users/wendyappleseed/events{/privacy}", | ||
"following_url": "https://api.github.com/users/wendyappleseed/following{/other_user}", | ||
"followers_url": "https://api.github.com/users/wendyappleseed/followers", | ||
"gists_url": "https://api.github.com/users/wendyappleseed/gists{/gist_id}", | ||
"organizations_url": "https://api.github.com/users/wendyappleseed/orgs", | ||
"received_events_url": "https://api.github.com/users/wendyappleseed/received_events", | ||
"repos_url": "https://api.github.com/users/wendyappleseed/repos", | ||
"starred_url": "https://api.github.com/users/wendyappleseed/starred{/owner}{/repo}", | ||
"subscriptions_url": "https://api.github.com/users/wendyappleseed/subscriptions" | ||
}, | ||
"labels": [ | ||
{ | ||
"id": 5728067083, | ||
"url": "https://api.github.com/repos/1Password/1password-teams-open-source/labels/status:%20approved", | ||
"name": "status: approved", | ||
"color": "0052CC", | ||
"description": "The application has been approved", | ||
"default": false, | ||
"node_id": "LA_kwDOJ6JE6M8AAAABVWteCw" | ||
} | ||
], | ||
"comments": 11, | ||
"closed_at": "2023-07-13T05:03:51Z", | ||
"created_at": "2023-07-12T19:49:35Z", | ||
"updated_at": "2023-07-13T05:03:51Z", | ||
"url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6", | ||
"html_url": "https://github.com/wendyappleseed/1password-teams-open-source/issues/6", | ||
"comments_url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/comments", | ||
"events_url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/events", | ||
"labels_url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/labels{/name}", | ||
"repository_url": "https://api.github.com/repos/1Password/1password-teams-open-source", | ||
"reactions": { | ||
"total_count": 0, | ||
"+1": 0, | ||
"-1": 0, | ||
"laugh": 0, | ||
"confused": 0, | ||
"heart": 0, | ||
"hooray": 0, | ||
"url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/reactions" | ||
}, | ||
"node_id": "I_kwDOJ6JE6M5rYwCY" | ||
} |
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,49 @@ | ||
{ | ||
"id": 1801650328, | ||
"number": 6, | ||
"state": "closed", | ||
"locked": false, | ||
"title": "Application for TestDB", | ||
"body": "### Account URL\n\ntestdb.1password.com\n\n### Non-commercial confirmation\n\n- [X] No, this account won't be used for commercial activity\n\n### Team application\n\n- [ ] Yes, this application is for a team\n\n### Event application\n\n- [ ] Yes, this application is for an event\n\n### Project name\n\nTestDB\n\n### Short description\n\nTestDB is a free and open source, community-based forum software project.\n\n### Number of team members/core contributors\n\n1\n\n### Homepage URL\n\nhttps://github.com/wendyappleed/test-db\n\n### Repository URL\n\nhttps://github.com/wendyappleed/test-db\n\n### License type\n\nMIT\n\n### License URL\n\nhttps://github.com/wendyappleed/test-db/blob/main/LICENSE.md\n\n### Age confirmation\n\n- [X] Yes, this project is at least 30 days old\n\n### Name\n\nWendy Appleseed\n\n### Email\n\nwendyappleseed@example.com\n\n### Project role\n\nCore Maintainer\n\n### Profile or website\n\nhttps://github.com/wendyappleseed/\n\n### Can we contact you?\n\n- [X] Yes, you may contact me\n\n### Additional comments\n\nThank you!", | ||
"user": { | ||
"login": "wendyappleseed", | ||
"id": 38230737, | ||
"node_id": "MDQ6VXNlcjYzOTIwNDk=", | ||
"avatar_url": "https://avatars.githubusercontent.com/u/38230737?v=4", | ||
"html_url": "https://github.com/wendyappleseed", | ||
"gravatar_id": "", | ||
"type": "User", | ||
"site_admin": false, | ||
"url": "https://api.github.com/users/wendyappleseed", | ||
"events_url": "https://api.github.com/users/wendyappleseed/events{/privacy}", | ||
"following_url": "https://api.github.com/users/wendyappleseed/following{/other_user}", | ||
"followers_url": "https://api.github.com/users/wendyappleseed/followers", | ||
"gists_url": "https://api.github.com/users/wendyappleseed/gists{/gist_id}", | ||
"organizations_url": "https://api.github.com/users/wendyappleseed/orgs", | ||
"received_events_url": "https://api.github.com/users/wendyappleseed/received_events", | ||
"repos_url": "https://api.github.com/users/wendyappleseed/repos", | ||
"starred_url": "https://api.github.com/users/wendyappleseed/starred{/owner}{/repo}", | ||
"subscriptions_url": "https://api.github.com/users/wendyappleseed/subscriptions" | ||
}, | ||
"comments": 11, | ||
"closed_at": "2023-07-13T05:03:51Z", | ||
"created_at": "2023-07-12T19:49:35Z", | ||
"updated_at": "2023-07-13T05:03:51Z", | ||
"url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6", | ||
"html_url": "https://github.com/wendyappleseed/1password-teams-open-source/issues/6", | ||
"comments_url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/comments", | ||
"events_url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/events", | ||
"labels_url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/labels{/name}", | ||
"repository_url": "https://api.github.com/repos/1Password/1password-teams-open-source", | ||
"reactions": { | ||
"total_count": 0, | ||
"+1": 0, | ||
"-1": 0, | ||
"laugh": 0, | ||
"confused": 0, | ||
"heart": 0, | ||
"hooray": 0, | ||
"url": "https://api.github.com/repos/1Password/1password-teams-open-source/issues/6/reactions" | ||
}, | ||
"node_id": "I_kwDOJ6JE6M5rYwCY" | ||
} |