diff --git a/.github/policies/auto-merge.yml b/.github/policies/auto-merge.yml index b3d49e0041..e8801d9bfc 100644 --- a/.github/policies/auto-merge.yml +++ b/.github/policies/auto-merge.yml @@ -16,9 +16,8 @@ configuration: label: ':octocat: auto-merge' - targetsBranch: branch: main - - or: - - isActivitySender: - user: dotnet-policy-service[bot] + - isActivitySender: + user: dotnet-policy-service[bot] then: - enableAutoMerge: mergeMethod: Squash @@ -46,3 +45,4 @@ configuration: label: ':octocat: auto-merge' then: - disableAutoMerge + diff --git a/.github/policies/close-issues.yml b/.github/policies/close-issues.yml index fdcebf4cb0..da7d8071ba 100644 --- a/.github/policies/close-issues.yml +++ b/.github/policies/close-issues.yml @@ -1,5 +1,5 @@ -name: Stale issues -description: Close needs-more-info issues that haven't had a response in 14 days +name: Close issues +description: Close issues based on label resource: repository where: configuration: @@ -19,3 +19,26 @@ configuration: - addReply: reply: This issue has been automatically closed due to no response from the original author. Feel free to reopen it if you have more information that can help us investigate the issue further. - closeIssue + + eventResponderTasks: + - description: Remove needs-more-info label when author comments on issue + if: + - payloadType: Issue_Comment + - isAction: + action: Created + - isActivitySender: + issueAuthor: True + - hasLabel: + label: needs-more-info + - isOpen + then: + - removeLabel: + label: needs-more-info + + - description: Close issues labeled 'code-of-conduct' + if: + - payloadType: Issues + - hasLabel: + label: code-of-conduct + then: + - closeIssue diff --git a/.github/policies/issueManagement-emptyIssue.yml b/.github/policies/issueManagement-emptyIssue.yml new file mode 100644 index 0000000000..0fb0fe5590 --- /dev/null +++ b/.github/policies/issueManagement-emptyIssue.yml @@ -0,0 +1,28 @@ +id: issueManagement.emptyIssue +name: GitOps.EmptyIssue +description: Checks for an issue created via learn that has an empty description from the template. +owner: +resource: repository +disabled: false +where: +configuration: + resourceManagementConfiguration: + eventResponderTasks: + - description: Close an issue created with the learn template that has an empty body. + if: + - payloadType: Issues + - bodyContains: + pattern: '### Description[\n\r]+\[Enter feedback here\][\n\r]+###' + isRegex: true + then: + - addLabel: 'needs-more-info' + - removeLabel: ':watch: Not Triaged' + - closeIssue + + triggerOnOwnActions: false + +onFailure: +onSuccess: + + + diff --git a/.github/policies/issueManagement-notTriaged.yml b/.github/policies/issueManagement-notTriaged.yml new file mode 100644 index 0000000000..bc5339fc53 --- /dev/null +++ b/.github/policies/issueManagement-notTriaged.yml @@ -0,0 +1,54 @@ +id: issueManagement.notTriaged +name: GitOps.NotTriagedHandler +description: Ensures the Not Triaged label is added or removed when appropriate +owner: +resource: repository +disabled: false +where: +configuration: + resourceManagementConfiguration: + eventResponderTasks: + - description: >- + Add "not triaged" label when: + * Issue is opened + * Issue is reopened + * 'needs-more-info' label removed + if: + - payloadType: Issues + - or: + + - or: + - isAction: + action: Opened + - isAction: + action: Reopened + + - labelRemoved: + label: 'needs-more-info' + then: + - addLabel: ':watch: Not Triaged' + triggerOnOwnActions: false + + - description: >- + Remove "not triaged" label when: + * Issue author closes the issue + * reQUEST label is added + if: + - payloadType: Issues + - hasLabel: + label: ':watch: Not Triaged' + - or: + - and: + - isAction: + action: Closed + - isActivitySender: + issueAuthor: true + + - labelAdded: + label: ':world_map: reQUEST' + then: + - removeLabel: ':watch: Not Triaged' + triggerOnOwnActions: false + +onFailure: +onSuccess: diff --git a/.github/policies/label-issues.yml b/.github/policies/label-issues.yml index 7ced254b88..355129250e 100644 --- a/.github/policies/label-issues.yml +++ b/.github/policies/label-issues.yml @@ -1,6 +1,6 @@ -id: -name: GitOps.PullRequestIssueManagement -description: GitOps.PullRequestIssueManagement primitive +id: label.issues +name: GitOps.IssueManagement +description: Management logic around issues owner: resource: repository disabled: false @@ -24,6 +24,56 @@ configuration: label: okr-quality eventResponderTasks: + - description: Label dependabot issues + if: + - payloadType: Issues + - isAction: + action: Opened + - or: + - isActivitySender: + user: dependabot + - isActivitySender: + user: dependabot[bot] + then: + - addLabel: + label: dependencies + + - description: Reopen issue so remove "won't fix" label + if: + - payloadType: Issues + - isAction: + action: Reopened + - hasLabel: + label: "won't fix" + + then: + - removeLabel: + label: "won't fix" + + - description: Remove "in-progress" label when issue closed + if: + - payloadType: Issues + - isAction: + action: Closed + - hasLabel: + label: 'in-progress' + + then: + - removeLabel: + label: 'in-progress' + + - description: Issue closed by author, add "resolved-by-customer" label + if: + - payloadType: Issues + - isAction: + action: Closed + - isActivitySender: + issueAuthor: true + + then: + - addLabel: + label: resolved-by-customer + - description: Add in-pr label to issues if: - payloadType: Pull_Request diff --git a/.github/policies/labelAdded-mapQuest.yml b/.github/policies/labelAdded-mapQuest.yml new file mode 100644 index 0000000000..4847c8fcc8 --- /dev/null +++ b/.github/policies/labelAdded-mapQuest.yml @@ -0,0 +1,25 @@ +id: labelAdded.mapQuest +name: GitOps.MapQuestHandler +description: Handles when "mapQUEST" label is added +owner: +resource: repository +disabled: false +where: +configuration: + resourceManagementConfiguration: + eventResponderTasks: + - description: >- + When the label "mapQUEST" is added to an issue + * Remove label "mapQUEST" + if: + - or: + - payloadType: Issues + - payloadType: Pull_Request + + - labelAdded: + label: ':world_map: mapQUEST' + then: + - removeLabel: ':world_map: mapQUEST' + triggerOnOwnActions: true +onFailure: +onSuccess: diff --git a/.github/policies/pullRequestManagement-serviceLabels.yml b/.github/policies/pullRequestManagement-serviceLabels.yml new file mode 100644 index 0000000000..be7a74700e --- /dev/null +++ b/.github/policies/pullRequestManagement-serviceLabels.yml @@ -0,0 +1,69 @@ +id: pullRequestManagement.serviceLabels +name: GitOps.PullRequestServiceLabels +description: Checks the files touched by a pull request and assigns area labels. +owner: +resource: repository +disabled: false +where: +configuration: + resourceManagementConfiguration: + eventResponderTasks: + - description: Add labels to PRs that touch certain files + triggerOnOwnActions: false + if: + - payloadType: Pull_Request + - or: + - isAction: + action: Opened + - isAction: + action: Synchronize + - not: + targetsBranch: + branch: live + then: + # Framework WPF + - if: + - filesMatchPattern: + pattern: '(?i).*dotnet-desktop-guide\/framework\/wpf.*' + matchAny: true + then: + - addLabel: + label: 'dotnet-framework/svc' + - addLabel: + label: 'wpf/subsvc' + + # Framework WinForms + - if: + - filesMatchPattern: + pattern: '(?i).*dotnet-desktop-guide\/framework\/winforms.*' + matchAny: true + then: + - addLabel: + label: 'dotnet-framework/svc' + - addLabel: + label: 'winforms/subsvc' + + # .NET WPF + - if: + - filesMatchPattern: + pattern: '(?i).*dotnet-desktop-guide\/net\/wpf.*' + matchAny: true + then: + - addLabel: + label: 'dotnet-desktop/svc' + - addLabel: + label: 'wpf/subsvc' + + # .NET WinForms + - if: + - filesMatchPattern: + pattern: '(?i).*dotnet-desktop-guide\/net\/winforms.*' + matchAny: true + then: + - addLabel: + label: 'dotnet-desktop/svc' + - addLabel: + label: 'winforms/subsvc' + +onFailure: +onSuccess: diff --git a/.repoman.yml b/.repoman.yml index 5d3112f031..8b064834ca 100644 --- a/.repoman.yml +++ b/.repoman.yml @@ -14,82 +14,7 @@ config: issues: - unlabeled: "labeled" - - labeled: - - # Temporary label to mark issues as updated for Quest. The label is instantly removed - - check: - - type: query - value: "length(Issue.Labels[?Name == ':world_map: mapQUEST']) != `0`" - pass: - - labels-remove: [":world_map: mapQUEST"] - - # Handle issues with /svc /subsvc labels from label bot - - - check: - - type: query - value: "length(Issue.Labels[?contains(Name, '/svc') || contains(Name, '/subsvc')]) != `0`" - - # If the issue has a /svc or /subsvc label, it must be categorized otherwise it's considered untriaged - pass: - - check: - - type: query - value: "length(Issue.Labels[?Name == ':pushpin: seQUESTered' || Name == ':world_map: reQUEST' || Name == 'training-module' || Name == 'doc-enhancement' || Name == 'product-question' || Name == 'in-progress' || Name == 'test-issue' || Name == 'kudos' || Name == 'loc' || Name == 'doc-bug' || Name == 'product-feedback' || Name == 'code-of-conduct' || Name == 'support-request' || Name == 'duplicate' || Name == 'resolved-by-customer' || Name == 'docs-experience' || Name == 'doc-provided' || Name == 'doc-idea' || Name == 'needs-more-info']) != `0`" - pass: - - labels-remove: [":watch: Not Triaged"] - fail: - - labels-add: [":watch: Not Triaged"] - - # Not an doc issue specifically - fail: - - # If the issue is open, then we'll allow some further processing on it. If it's closed, ignore it and let the user do what they want. - - check: - - type: query - value: "Issue.State.StringValue == 'open'" - - pass: - - check: - - type: query - value: "length(Issue.Labels[?Name == ':pushpin: seQUESTered' || Name == ':world_map: reQUEST' || Name == 'training-module' || Name == 'video-content'] || Name == 'test-issue') != `0`" - pass: - - labels-remove: [":watch: Not Triaged"] - fail: - - labels-add: [":watch: Not Triaged"] - - # Checks for binary/source incompatible checkboxes and adds a label - - check: - - type: query - value: "contains(InstanceData.IssuePrBody, '- [x] **Binary incompatible**') == `true` || contains(InstanceData.IssuePrBody, '- [X] **Binary incompatible**') == `true`" - pass: - - labels-add: ["binary incompatible"] - - - check: - - type: query - value: "contains(InstanceData.IssuePrBody, '- [x] **Source incompatible**') == `true` || contains(InstanceData.IssuePrBody, '- [X] **Source incompatible**') == `true`" - pass: - - labels-add: ["source incompatible"] - opened: - # New issue opened, add Not Triaged - - labels-add: [":watch: Not Triaged"] - - # Dependabot opened issue, label it - - check: - - type: query - value: "Issue.User.Login == 'dependabot'" - pass: - - labels-add: ["dependencies"] - - # Try to detect an empty issue - - check: - - type: comment-body - value: "### Description[\\n\\r]+\\[Enter feedback here\\][\\n\\r]+###" - pass: - - labels-add: ["needs-more-info"] - - labels-remove: [":watch: Not Triaged"] - - close # Add links to related issues if it's a doc issue - check: @@ -99,23 +24,10 @@ issues: pass: - link-related-issues - reopened: - - # Remove won't fix label - - labels-remove: ["won't fix"] - - closed: - - # Issue closed, remove in-progress and not triaged labels - - labels-remove: ["in-progress", ":watch: Not Triaged"] - - # Check if the issue was closed by the user who opened it - check: - - type: query - value: "Issue.User.Id == EventPayload.sender.id" + - type: metadata-exists pass: - - labels-add: ["resolved-by-customer"] - - labels-remove: [":watch: Not Triaged"] + - svc_subsvc_labels: true pull_request: @@ -125,27 +37,6 @@ pull_request: # Set default sprint for new PRs - milestone-set: "![sprint]" - - - check: - - type: query - value: "PullRequest.Base.Ref != 'live'" - pass: - - files-changed: - - path: "(?i).*dotnet-desktop-guide\/framework\/wpf.*" - run: - - labels-add: ["dotnet-framework/svc", "wpf/subsvc"] - - - path: "(?i).*dotnet-desktop-guide\/framework\/winforms.*" - run: - - labels-add: ["dotnet-framework/svc", "winforms/subsvc"] - - - path: "(?i).*dotnet-desktop-guide\/net\/wpf.*" - run: - - labels-add: ["dotnet-desktop/svc", "wpf/subsvc"] - - - path: "(?i).*dotnet-desktop-guide\/net\/winforms.*" - run: - - labels-add: ["dotnet-desktop/svc", "winforms/subsvc"] projects_v2_item: @@ -160,16 +51,3 @@ projects_v2_item: value: "EventPayload.changes.field_value.field_name == 'Priority' || EventPayload.changes.field_value.field_name == 'Size'" pass: - labels-add: [":world_map: mapQUEST"] - -issue_comment: - - created: - - # someone creates a comment with #please-review in it, add changes-addressed label - - check: - - type: query - value: "Issue.State.StringValue == 'open' && Issue.User.Id == Comment.User.Id" - - type: comment-body - value: ^#please-review$ - pass: - - labels-add: ["changes-addressed"]