├── .ruby-version ├── .github ├── src │ └── incident_resolved.png ├── label-actions.yml ├── actions │ ├── remove_inactive_label │ ├── close │ ├── update_incident_discussion.rb │ ├── resolve_incident_discussion.rb │ ├── open_incident_discussion.rb │ ├── comment │ ├── close_incident_discussions.rb │ ├── post_incident_summary.rb │ └── add_feedback_comment ├── DISCUSSION_TEMPLATE │ ├── npm.yml │ ├── feed.yml │ ├── lists.yml │ ├── packages.yml │ ├── pages.yml │ ├── profile.yml │ ├── models.yml │ ├── sponsors.yml │ ├── code-security.yml │ ├── enterprise.yml │ ├── pull-requests.yml │ ├── repositories.yml │ ├── api-and-webhooks.yml │ ├── code-search-and-navigation.yml │ ├── codespaces.yml │ ├── programming-help.yml │ ├── general.yml │ ├── mobile.yml │ ├── discussions.yml │ ├── copilot-conversations.yml │ ├── projects-and-issues.yml │ ├── accessibility.yml │ ├── actions.yml │ └── github-education.yml ├── workflows │ ├── close-dormant-discussions.yml │ ├── comment-on-dormant-discussions.yml │ ├── remove-inactive-label.yml │ ├── add-feedback-comment.yml │ ├── close-incident-discussions.yml │ ├── open-incident-discussion.yml │ ├── update-incident-discussion-as-resolved.yml │ ├── post-incident-summary.yml │ ├── update-incident-discussion.yml │ ├── auto-close-pr.yml │ ├── remove-governed-labels-on-label.yml │ ├── issue_projects_labeler.yml │ ├── label-templated-discussions.yml │ ├── remove-governed-labels-on-create.yml │ ├── recategorize-discussions.yml │ ├── Accessibility-Labeler.yml │ ├── copilot_labeller.yml │ └── actions_labeller.yml └── lib │ ├── categories.rb │ ├── github.rb │ └── discussions.rb ├── .rubocop.yml ├── Gemfile ├── LICENSE-CODE ├── Gemfile.lock ├── docs ├── Meet the Maintainers Sweepstakes Rules.md ├── Accessibility Skills Student Series Spring 2025.md ├── Spring 2025 GitHub Foundation Certification Prep Course Sweepstakes Official Rules.md ├── Responsible-AI-for-Open-Source-Sweepstakes-Official-Rules.md └── Fall2025-GitHub-Administration-Certification-Prep-Course-Sweepstakes.md ├── README.md ├── CODE_OF_CONDUCT.md └── LICENSE /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.3.5 2 | -------------------------------------------------------------------------------- /.github/src/incident_resolved.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Community/community/main/.github/src/incident_resolved.png -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | NewCops: enable 3 | inherit_gem: 4 | rubocop-github: 5 | - config/default.yml 6 | - config/rails.yml 7 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "faraday" 6 | 7 | group :test, :development do 8 | gem "rubocop-github" 9 | end 10 | -------------------------------------------------------------------------------- /.github/label-actions.yml: -------------------------------------------------------------------------------- 1 | # Configuration for Label Actions - remove label id 2 | 3 | more information needed: 4 | discussions: 5 | # Remove labels 6 | unlabel: 7 | - 'more information needed' 8 | 9 | in backlog: 10 | discussions: 11 | unlabel: 12 | - 'in backlog' 13 | 14 | fixed: 15 | discussions: 16 | unlabel: 17 | - 'fixed' 18 | -------------------------------------------------------------------------------- /.github/actions/remove_inactive_label: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative "../lib/github" 5 | 6 | stale_label_id = "LA_kwDOEfmk4M8AAAABYVCU-g" 7 | owner = "community" 8 | repo = "community" 9 | 10 | node_id = ENV['NODE_ID'] 11 | puts "Removing the inactive label from #{node_id}" 12 | Discussion.remove_label(node_id: node_id, label_id: stale_label_id) 13 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/npm.yml: -------------------------------------------------------------------------------- 1 | labels: [npm] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/feed.yml: -------------------------------------------------------------------------------- 1 | labels: [Feed] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/lists.yml: -------------------------------------------------------------------------------- 1 | labels: [Lists] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/packages.yml: -------------------------------------------------------------------------------- 1 | labels: [Packages] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/pages.yml: -------------------------------------------------------------------------------- 1 | labels: [Pages] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/profile.yml: -------------------------------------------------------------------------------- 1 | labels: [Profile] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/models.yml: -------------------------------------------------------------------------------- 1 | labels: [Models] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/sponsors.yml: -------------------------------------------------------------------------------- 1 | labels: [Sponsors] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/code-security.yml: -------------------------------------------------------------------------------- 1 | labels: [Code Security] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/enterprise.yml: -------------------------------------------------------------------------------- 1 | labels: [Enterprise] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/pull-requests.yml: -------------------------------------------------------------------------------- 1 | labels: [Pull Requests] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/repositories.yml: -------------------------------------------------------------------------------- 1 | labels: [Repositories] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/api-and-webhooks.yml: -------------------------------------------------------------------------------- 1 | labels: [API and Webhooks] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/code-search-and-navigation.yml: -------------------------------------------------------------------------------- 1 | labels: [Code Search and Navigation] 2 | body: 3 | - type: dropdown 4 | attributes: 5 | label: Select Topic Area 6 | description: What would you like to discuss? 7 | options: 8 | - "Question" 9 | - "Product Feedback" 10 | - "Bug" 11 | - "Show & Tell" 12 | - "General" 13 | validations: 14 | required: true 15 | - type: textarea 16 | attributes: 17 | label: Body 18 | description: Start your discussion! 19 | validations: 20 | required: true 21 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/codespaces.yml: -------------------------------------------------------------------------------- 1 | labels: [Codespaces] 2 | body: 3 | - type: dropdown 4 | id: topic 5 | attributes: 6 | label: Select Topic Area 7 | description: What would you like to discuss? 8 | options: 9 | - "Question" 10 | - "Product Feedback" 11 | - "Bug" 12 | - "Show & Tell" 13 | - "General" 14 | validations: 15 | required: true 16 | - type: textarea 17 | id: text 18 | attributes: 19 | label: Body 20 | description: Start your discussion! 21 | validations: 22 | required: true 23 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/programming-help.yml: -------------------------------------------------------------------------------- 1 | labels: [Programming Help] 2 | body: 3 | - type: markdown 4 | attributes: 5 | value: Start your discussion! 6 | validations: 7 | required: true 8 | - type: textarea 9 | attributes: 10 | label: Body 11 | description: Start your discussion! 12 | validations: 13 | required: true 14 | - type: checkboxes 15 | attributes: 16 | label: Guidelines 17 | options: 18 | - label: I have read and understood this category's [guidelines](https://github.com/orgs/community/discussions/51384) before making this post. 19 | required: true 20 | -------------------------------------------------------------------------------- /.github/actions/close: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative "../lib/github" 5 | 6 | stale_label_id = "LA_kwDOEfmk4M8AAAABYVCU-g" 7 | owner = "community" 8 | repo = "community" 9 | 10 | discussions = Discussion.to_be_closed(owner:, repo:) 11 | puts "All: #{discussions.count}" 12 | 13 | discussions.each do |discussion| 14 | puts "#{discussion.url} - #{discussion.title}" 15 | result = discussion.close_as_outdated 16 | if errors = result.dig("errors") 17 | puts "#{errors.dig(0, "type")}: #{errors.dig(0, "message")}" 18 | exit 19 | end 20 | 21 | sleep 10 22 | end 23 | -------------------------------------------------------------------------------- /.github/workflows/close-dormant-discussions.yml: -------------------------------------------------------------------------------- 1 | name: Close out dormant discussions 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | # At 01:25 every day 7 | - cron: "5 0 * * *" 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | discussions: write 15 | steps: 16 | - name: Checkout Repository 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up Ruby 20 | uses: ruby/setup-ruby@v1 21 | 22 | - name: Bundle install 23 | run: bundle install 24 | 25 | - name: Close out discussions 26 | run: .github/actions/close 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | 30 | -------------------------------------------------------------------------------- /.github/workflows/comment-on-dormant-discussions.yml: -------------------------------------------------------------------------------- 1 | name: Comment on dormant discussions 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | # At 03:25 every day 7 | - cron: "5 0 * * *" 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | contents: read 14 | discussions: write 15 | steps: 16 | - name: Checkout Repository 17 | uses: actions/checkout@v4 18 | 19 | - name: Set up Ruby 20 | uses: ruby/setup-ruby@v1 21 | 22 | - name: Bundle install 23 | run: bundle install 24 | 25 | - name: Comment on discussions 26 | run: .github/actions/comment 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | -------------------------------------------------------------------------------- /.github/workflows/remove-inactive-label.yml: -------------------------------------------------------------------------------- 1 | name: Remove the inactive label 2 | 3 | on: 4 | discussion_comment: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: read 12 | discussions: write 13 | steps: 14 | - name: Checkout Repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Set up Ruby 18 | uses: ruby/setup-ruby@v1 19 | 20 | - name: Bundle install 21 | run: bundle install 22 | 23 | - name: Remove the label 24 | run: .github/actions/remove_inactive_label 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | NODE_ID: ${{ github.event.discussion.node_id }} 28 | -------------------------------------------------------------------------------- /.github/workflows/add-feedback-comment.yml: -------------------------------------------------------------------------------- 1 | name: Add a feedback comment when a discussion gets a related label 2 | 3 | on: 4 | discussion: 5 | types: [created,labeled] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: read 12 | discussions: write 13 | steps: 14 | - name: Checkout Repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Set up Ruby 18 | uses: ruby/setup-ruby@v1 19 | 20 | - name: Bundle install 21 | run: bundle install 22 | 23 | - name: Add feedback comment 24 | run: .github/actions/add_feedback_comment 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | DISCUSSION_NUMBER: ${{ github.event.discussion.number }} 28 | NODE_ID: ${{ github.event.discussion.node_id }} 29 | -------------------------------------------------------------------------------- /.github/actions/update_incident_discussion.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative "../lib/github" 5 | require_relative "../lib/discussions" 6 | 7 | # This script takes the context from the latest update dispatch event and updates the active incident discussion 8 | 9 | # first, we must identify the correct incident to update, in the case where there are multiple open incident discussions. 10 | discussion = Discussion.find_open_incident_discussions(owner: "community", repo: "community").keep_if { |d| d.body.include?("#{ENV["INCIDENT_SLUG"]}") }.first 11 | 12 | if discussion.nil? 13 | puts "No applicable discussion, exiting" 14 | exit 15 | end 16 | 17 | # next, we need to update the discussion with the new information 18 | update = "### Update \n #{ENV["INCIDENT_MESSAGE"]}" 19 | 20 | discussion.add_comment(body: update) 21 | -------------------------------------------------------------------------------- /.github/workflows/close-incident-discussions.yml: -------------------------------------------------------------------------------- 1 | name: Close incident discussion after time elapsed 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | # daily at midnight UTC 7 | - cron: "5 0 * * *" 8 | 9 | jobs: 10 | close_incident_post: 11 | runs-on: ubuntu-latest 12 | permissions: 13 | actions: read 14 | contents: read 15 | discussions: write 16 | steps: 17 | - name: Checkout Repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Set up Ruby 21 | uses: ruby/setup-ruby@7bae1d00b5db9166f4f0fc47985a3a5702cb58f0 22 | 23 | - name: Bundle install 24 | run: bundle install 25 | 26 | - name: Close incident discussions 27 | id: close_discussions 28 | run: .github/actions/close_incident_discussions.rb 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | -------------------------------------------------------------------------------- /.github/lib/categories.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Category = Struct.new( 4 | :id, 5 | :name, 6 | :answerable, 7 | :discussions 8 | ) do 9 | def self.all(owner: nil, repo: nil) 10 | return [] if owner.nil? || repo.nil? 11 | 12 | query = <<~QUERY 13 | { 14 | repository(owner: "#{owner}", name: "#{repo}"){ 15 | discussionCategories(first: 100) { 16 | nodes { 17 | id 18 | name 19 | isAnswerable 20 | } 21 | } 22 | } 23 | rateLimit { 24 | limit 25 | cost 26 | remaining 27 | resetAt 28 | } 29 | } 30 | QUERY 31 | 32 | GitHub.new.post(graphql: query).first.dig("discussionCategories", "nodes") 33 | .map do |c| 34 | Category.new( 35 | c["id"], 36 | c["name"], 37 | c["isAnswerable"] 38 | ) 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /.github/workflows/open-incident-discussion.yml: -------------------------------------------------------------------------------- 1 | name: Open a new discussion when an incident is declared 2 | 3 | on: 4 | repository_dispatch: 5 | types: [incident-declared] 6 | 7 | jobs: 8 | open_discussion: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | actions: read 12 | contents: read 13 | discussions: write 14 | steps: 15 | - name: Checkout Repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up Ruby 19 | uses: ruby/setup-ruby@7bae1d00b5db9166f4f0fc47985a3a5702cb58f0 20 | 21 | - name: Bundle install 22 | run: bundle install 23 | 24 | - name: Open discussion 25 | id: open_discussion 26 | run: .github/actions/open_incident_discussion.rb 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | PUBLIC_TITLE: ${{ github.event.client_payload.publicTitle }} 30 | INCIDENT_URL: ${{ github.event.client_payload.incidentLink }} 31 | -------------------------------------------------------------------------------- /LICENSE-CODE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) GitHub 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/general.yml: -------------------------------------------------------------------------------- 1 | labels: [General] 2 | body: 3 | - type: markdown 4 | attributes: 5 | value: 6 | ⚠️ The Community can not help with account-related issues, such as reinstatement requests or help to escalate your [GitHub Support](https://support.github.com/contact) tickets. ⚠️ 7 | - type: markdown 8 | attributes: 9 | value: 10 | 📛 We made the decision to disable the ability to earn Achievements in our Community in order to discourage users from participating in coordinated or inauthentic activity like rapid questions and answers in order to earn badges. You can learn more about this decision in our announcement post here [Achievements will no longer be available in the Community](https://github.com/orgs/community/discussions/106536) 📛 11 | - type: dropdown 12 | attributes: 13 | label: Select Topic Area 14 | description: What would you like to discuss? 15 | options: 16 | - "Question" 17 | - "Product Feedback" 18 | - "Bug" 19 | - "Show & Tell" 20 | - "General" 21 | validations: 22 | required: true 23 | - type: textarea 24 | attributes: 25 | label: Body 26 | description: Start your discussion! 27 | validations: 28 | required: true 29 | -------------------------------------------------------------------------------- /.github/actions/resolve_incident_discussion.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative "../lib/github" 5 | require_relative "../lib/discussions" 6 | 7 | # This script acts when we receieve an incident resolved dispatch event to update the incident discussion. 8 | 9 | # first, we must identify the correct incident to update, in the case where there are multiple open incident discussions. 10 | discussion = Discussion.find_open_incident_discussions(owner: "community", repo: "community").keep_if { |d| d.body.include?("#{ENV["INCIDENT_SLUG"]}") }.first 11 | 12 | if discussion.nil? 13 | puts "No applicable discussion, exiting" 14 | exit 15 | end 16 | 17 | discussion.add_comment(body: "### Incident Resolved \n This incident has been resolved.") 18 | # update the post body to include the resolved picture 19 | updated_body = "![A dark background with two security-themed abstract shapes positioned in the top left and bottom right corners. In the center of the image, bold white text reads \\\"Incident Resolved\\\" with a white Octocat logo.](https://github.com/community/community/blob/main/.github/src/incident_resolved.png?raw=true) \n \n #{discussion.body}" 20 | discussion.update_discussion(body: updated_body) 21 | -------------------------------------------------------------------------------- /.github/workflows/update-incident-discussion-as-resolved.yml: -------------------------------------------------------------------------------- 1 | name: Mark incident discussion as resolved 2 | 3 | on: 4 | repository_dispatch: 5 | types: [incident-resolved] 6 | 7 | jobs: 8 | resolve_discussion: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | actions: read 12 | contents: read 13 | discussions: write 14 | steps: 15 | - name: Checkout Repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up Ruby 19 | uses: ruby/setup-ruby@7bae1d00b5db9166f4f0fc47985a3a5702cb58f0 20 | 21 | - name: Bundle install 22 | run: bundle install 23 | 24 | - name: Get incident URL slug 25 | id: incident_slug 26 | uses: actions/github-script@v7 27 | with: 28 | result-encoding: string 29 | script: | 30 | const url = "${{ github.event.client_payload.incidentLink }}" 31 | const slug = url.split('/').pop(); 32 | return slug 33 | 34 | - name: Mark incident discussion as resolved 35 | id: mark_resolved 36 | run: .github/actions/resolve_incident_discussion.rb 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | INCIDENT_SLUG: ${{ steps.incident_slug.outputs.result }} -------------------------------------------------------------------------------- /.github/workflows/post-incident-summary.yml: -------------------------------------------------------------------------------- 1 | name: Post incident summary to incident discussion 2 | 3 | on: 4 | repository_dispatch: 5 | types: [incident-public-summary] 6 | 7 | jobs: 8 | post_summary: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | actions: read 12 | contents: read 13 | discussions: write 14 | steps: 15 | - name: Checkout Repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up Ruby 19 | uses: ruby/setup-ruby@7bae1d00b5db9166f4f0fc47985a3a5702cb58f0 20 | 21 | - name: Bundle install 22 | run: bundle install 23 | 24 | - name: Get incident URL slug 25 | id: incident_slug 26 | uses: actions/github-script@v7 27 | with: 28 | result-encoding: string 29 | script: | 30 | const url = "${{ github.event.client_payload.incidentLink }}" 31 | const slug = url.split('/').pop(); 32 | return slug 33 | 34 | - name: Add comment to incident discussion 35 | id: add_comment 36 | run: .github/actions/post_incident_summary.rb 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | INCIDENT_SLUG: ${{ steps.incident_slug.outputs.result }} 40 | INCIDENT_PUBLIC_SUMMARY: ${{ github.event.client_payload.message }} 41 | -------------------------------------------------------------------------------- /.github/workflows/update-incident-discussion.yml: -------------------------------------------------------------------------------- 1 | name: Update current incident discussion with new information 2 | 3 | on: 4 | repository_dispatch: 5 | types: [incident-public-update] 6 | 7 | jobs: 8 | update_discussion: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | actions: read 12 | contents: read 13 | discussions: write 14 | steps: 15 | - name: Checkout Repository 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up Ruby 19 | uses: ruby/setup-ruby@7bae1d00b5db9166f4f0fc47985a3a5702cb58f0 20 | 21 | - name: Bundle install 22 | run: bundle install 23 | 24 | - name: Get incident URL slug 25 | id: incident_slug 26 | uses: actions/github-script@v7 27 | with: 28 | result-encoding: string 29 | script: | 30 | const url = "${{ github.event.client_payload.incidentLink }}" 31 | const slug = url.split('/').pop(); 32 | return slug 33 | 34 | - name: Add comment to incident discussion 35 | id: add_comment 36 | run: .github/actions/update_incident_discussion.rb 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | INCIDENT_SLUG: ${{ steps.incident_slug.outputs.result }} 40 | INCIDENT_MESSAGE: ${{ github.event.client_payload.message }} 41 | -------------------------------------------------------------------------------- /.github/actions/open_incident_discussion.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative "../lib/github" 5 | require_relative "../lib/discussions" 6 | require "active_support/core_ext/date_time" 7 | 8 | # This script takes context from a received webhook and creates a new discussion in the correct discussion category 9 | 10 | repo_id = "MDEwOlJlcG9zaXRvcnkzMDE1NzMzNDQ=" 11 | announcements_category_id = "DIC_kwDOEfmk4M4CQbR2" 12 | incident_label_id = "LA_kwDOEfmk4M8AAAABpaZlTA" 13 | 14 | date = Time.now.strftime("%Y-%m-%d") 15 | 16 | # we need to take the provided input and generate a new post 17 | title = "[#{date}] Incident Thread" 18 | 19 | body = <<~BODY 20 | ## :exclamation: An incident has been declared: 21 | 22 | **#{ENV['PUBLIC_TITLE']}** 23 | 24 | _Subscribe to this Discussion for updates on this incident. Please upvote or emoji react instead of commenting +1 on the Discussion to avoid overwhelming the thread. Any account guidance specific to this incident will be shared in thread and on the [Incident Status Page](#{ENV['INCIDENT_URL']})._ 25 | BODY 26 | 27 | # we need to create a new discussion in the correct category with the correct label 28 | begin 29 | Discussion.create_incident_discussion( 30 | repo_id:, 31 | title:, 32 | body:, 33 | category_id: announcements_category_id, 34 | labels: [incident_label_id] 35 | ) 36 | rescue => ArgumentError 37 | puts "ERROR: One or more arguments missing. #{ArgumentError.message}" 38 | end 39 | -------------------------------------------------------------------------------- /.github/actions/comment: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative "../lib/github" 5 | 6 | stale_label_id = "LA_kwDOEfmk4M8AAAABYVCU-g" 7 | owner = "community" 8 | repo = "community" 9 | 10 | body =<- 35 | Provide a detailed description of your discussion (e.g., What issue are you facing? What feedback do you have? What question do you need answered?). Please include logs wherever possible. 36 | validations: 37 | required: true 38 | - type: markdown 39 | attributes: 40 | value: | 41 | #### Don't forget to mark an [answer as "solved"](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#marking-a-comment-as-an-answer) to help others with similar questions. ✅ 42 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/discussions.yml: -------------------------------------------------------------------------------- 1 | title: "" 2 | labels: [Discussions] 3 | body: 4 | - type: markdown 5 | attributes: 6 | value: | 7 | ⚠️ This category is solely for discussions and feedback on [the GitHub Discussions product](https://github.com/features/discussions). ⚠️ 8 | 9 | [GitHub Discussions](https://github.com/features/discussions) is a product within GitHub that allows users to talk, ask questions, and share ideas. Discussions are meant for open-ended conversations. 10 | 11 | ### ✅ Dos - Use this category if your post is about 12 | - How to enable or configure **GitHub Discussions** in a repository or organization 13 | - Questions about **GitHub Discussions** features, such as marking answers, organizing threads or using moderation tools. 14 | - Bugs or issues specifically related to **GitHub Discussions** 🐞 15 | - Suggestions or feedback to improve the **GitHub Discussions** product 💬 16 | 17 | ### 🚫 Don'ts - Please, don't use this category for: 18 | - General troubleshooting, water cooler conversations or off-topic questions - have you tried General or Programming Help? 19 | - Feedback that doesn't directly relate to _GitHub Discussions_, that feedback belong somewhere else, use this [quick guide](https://github.com/orgs/community/discussions/151702) to help. 20 | 21 | ### 📚 Need help understanding how GitHub Discussions works? 22 | Read the official documentation: [GitHub Discussions Docs](https://docs.github.com/en/discussions) 23 | 24 | - type: dropdown 25 | attributes: 26 | label: "Discussion Type" 27 | description: What would you like to discuss? 28 | options: 29 | - "Product Feedback" 30 | - "Question" 31 | - "Bug" 32 | - "Show & Tell" 33 | - "General" 34 | validations: 35 | required: true 36 | - type: textarea 37 | attributes: 38 | label: "Discussion Content" 39 | description: Start your discussion! 40 | validations: 41 | pattern: "^.{1000,}$" 42 | regexFlags: "s" 43 | note: "Must have at least 1000 characters" 44 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activesupport (7.1.3.2) 5 | base64 6 | bigdecimal 7 | concurrent-ruby (~> 1.0, >= 1.0.2) 8 | connection_pool (>= 2.2.5) 9 | drb 10 | i18n (>= 1.6, < 2) 11 | minitest (>= 5.1) 12 | mutex_m 13 | tzinfo (~> 2.0) 14 | ast (2.4.2) 15 | base64 (0.2.0) 16 | bigdecimal (3.1.6) 17 | concurrent-ruby (1.2.3) 18 | connection_pool (2.4.1) 19 | drb (2.2.1) 20 | faraday (2.12.1) 21 | faraday-net_http (>= 2.0, < 3.5) 22 | json 23 | logger 24 | faraday-net_http (3.4.0) 25 | net-http (>= 0.5.0) 26 | i18n (1.14.4) 27 | concurrent-ruby (~> 1.0) 28 | json (2.7.1) 29 | language_server-protocol (3.17.0.3) 30 | logger (1.6.1) 31 | minitest (5.22.2) 32 | mutex_m (0.2.0) 33 | net-http (0.5.0) 34 | uri 35 | parallel (1.24.0) 36 | parser (3.3.0.5) 37 | ast (~> 2.4.1) 38 | racc 39 | racc (1.7.3) 40 | rack (3.0.9.1) 41 | rainbow (3.1.1) 42 | regexp_parser (2.9.0) 43 | rexml (3.3.6) 44 | strscan 45 | rubocop (1.62.0) 46 | json (~> 2.3) 47 | language_server-protocol (>= 3.17.0) 48 | parallel (~> 1.10) 49 | parser (>= 3.3.0.2) 50 | rainbow (>= 2.2.2, < 4.0) 51 | regexp_parser (>= 1.8, < 3.0) 52 | rexml (>= 3.2.5, < 4.0) 53 | rubocop-ast (>= 1.31.1, < 2.0) 54 | ruby-progressbar (~> 1.7) 55 | unicode-display_width (>= 2.4.0, < 3.0) 56 | rubocop-ast (1.31.1) 57 | parser (>= 3.3.0.4) 58 | rubocop-github (0.20.0) 59 | rubocop (>= 1.37) 60 | rubocop-performance (>= 1.15) 61 | rubocop-rails (>= 2.17) 62 | rubocop-performance (1.20.2) 63 | rubocop (>= 1.48.1, < 2.0) 64 | rubocop-ast (>= 1.30.0, < 2.0) 65 | rubocop-rails (2.24.0) 66 | activesupport (>= 4.2.0) 67 | rack (>= 1.1) 68 | rubocop (>= 1.33.0, < 2.0) 69 | rubocop-ast (>= 1.31.1, < 2.0) 70 | ruby-progressbar (1.13.0) 71 | strscan (3.1.0) 72 | tzinfo (2.0.6) 73 | concurrent-ruby (~> 1.0) 74 | unicode-display_width (2.5.0) 75 | uri (1.0.2) 76 | 77 | PLATFORMS 78 | arm64-darwin-21 79 | arm64-darwin-24 80 | x86_64-linux 81 | 82 | DEPENDENCIES 83 | faraday 84 | rubocop-github 85 | 86 | BUNDLED WITH 87 | 2.4.19 88 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/copilot-conversations.yml: -------------------------------------------------------------------------------- 1 | body: 2 | - type: markdown 3 | attributes: 4 | value: | 5 | #### Explore our [Copilot FAQs](https://github.com/orgs/community/discussions/144674) and [GitHub Docs](https://docs.github.com/en/copilot) for comprehensive guidance! 6 | - 💡 **Quick Tip:** For general development questions or detailed code issues, try [Chat with Copilot](https://docs.github.com/en/enterprise-cloud@latest/copilot/using-github-copilot/copilot-chat/asking-github-copilot-questions-in-github) first, it might have the answer you need before posting here. 7 | - 🛠️ For bugs and feature requests related to Copilot in VS Code, please open an issue in our [VS Code repo](https://github.com/microsoft/vscode/issues). If your issue is related to Copilot Chat, please [visit our FAQ](https://aka.ms/vscode-report-ai-feedback). 8 | - 🔍 Are you a student/teacher looking to enable Copilot Pro? [Read our guide](https://gh.io/faq-nd-copilot) 9 | - type: dropdown 10 | attributes: 11 | label: Select Topic Area 12 | description: What would you like to discuss about GitHub Copilot? Choose your topic area. 13 | options: 14 | - Question 15 | - Product Feedback 16 | - Bug 17 | - General 18 | validations: 19 | required: true 20 | - type: dropdown 21 | id: feature-area 22 | attributes: 23 | label: Copilot Feature Area 24 | description: Which Copilot feature or product area is your discussion related to? 25 | options: 26 | - General 27 | - Copilot in GitHub 28 | - Copilot Workspace 29 | - Copilot Agent Mode 30 | - Copilot Coding Agent 31 | - Copilot Enterprise 32 | - Account Related 33 | - VS Code 34 | - Visual Studio 35 | - JetBrains & Xcode 36 | validations: 37 | required: true 38 | - type: textarea 39 | attributes: 40 | label: Body 41 | description: Start your discussion! 42 | placeholder: >- 43 | Provide a detailed description of your discussion (e.g., What issue are you facing? What feedback do you have? What question do you need answered?) 44 | validations: 45 | required: true 46 | - type: markdown 47 | attributes: 48 | value: | 49 | #### Don't forget to mark an [answer as "solved"](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#marking-a-comment-as-an-answer) to help others with similar questions. ✅ 50 | -------------------------------------------------------------------------------- /.github/actions/add_feedback_comment: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative "../lib/github" 5 | 6 | owner = "community" 7 | repo = "community" 8 | 9 | body =< 5 | ⚠️ This category is solely for conversations related to the GitHub 6 | feature areas 7 | [Issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues) 8 | and 9 | [Projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects). 10 | ⚠️ 11 | - type: dropdown 12 | attributes: 13 | label: Select Topic Area 14 | description: What would you like to discuss? 15 | options: 16 | - Question 17 | - Product Feedback 18 | - Bug 19 | - Show & Tell 20 | - General 21 | validations: 22 | required: true 23 | - type: dropdown 24 | attributes: 25 | label: Feature Area 26 | description: > 27 | What GitHub product/feature area would you like to discuss? This 28 | category is only for conversations related to the below. 29 | 30 | Issues (The feature that allows you to track ideas, feedback, tasks, or bugs for work on GitHub. Not for any issue you are having). 31 | 32 | Projects (For planning and tracking work on GitHub - not any open source or other type of project). 33 | options: 34 | - Issues 35 | - Projects 36 | validations: 37 | required: true 38 | - type: textarea 39 | attributes: 40 | label: Body 41 | description: Start your discussion! 42 | placeholder: >- 43 | STOP! GitHub Issues refers to the issues you open in a repo to 44 | track your work. NOT issues you are having with GitHub or a GitHub 45 | product. GitHub Projects are project boards you can create for example 46 | Kanban boards, to track your work. NOT projects on GitHub. To ensure you receive a timely response by the correct team(s), make sure you are posting in the right category. 47 | validations: 48 | required: true 49 | - type: checkboxes 50 | attributes: 51 | label: Guidelines 52 | options: 53 | - label: I have read the above statement and can confirm my post is relevant to 54 | the GitHub feature areas 55 | [Issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues) 56 | and/or 57 | [Projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects/learning-about-projects/about-projects). 58 | required: true 59 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/accessibility.yml: -------------------------------------------------------------------------------- 1 | labels: [Accessibility] 2 | body: 3 | - type: markdown 4 | attributes: 5 | value: 6 | ⚠️ This category is solely for discussions and feedback on [the digital accessibility of GitHub products](https://accessibility.github.com/). ⚠️ 7 | 8 | Please use this space for questions, bug reports, opportunities, and feedback related to making GitHub features accessible to users of all abilities. 9 | 10 | To ensure you receive a timely response and connect with the proper team(s), please post in the correct category, questions about access, 2FA, and SMS belong in the [General category](https://github.com/orgs/community/discussions/categories/general?discussions_q=is%3Aopen+category%3AGeneral). Discussions that are posted in the wrong category may be moved. Users who post spam or violate of our [Code of Conduct](https://github.com/github/.github/blob/95e9dcb0b8b70a25cdb75de29f600812a07eb996/CODE_OF_CONDUCT.md) will be blocked. 11 | - type: dropdown 12 | attributes: 13 | label: Select Topic Area 14 | description: What would you like to discuss? 15 | options: 16 | - "Question" 17 | - "Product Feedback" 18 | - "Bug" 19 | - "Show & Tell" 20 | - "General" 21 | validations: 22 | required: true 23 | - type: dropdown 24 | attributes: 25 | label: GitHub Feature Area 26 | description: > 27 | What GitHub product/feature area is your Accessibility post related to? 28 | options: 29 | - Actions 30 | - APIs and Webhooks 31 | - Code Scanning 32 | - Code Search and Navigation 33 | - Code Security 34 | - Codespaces 35 | - Command Palette 36 | - Copilot 37 | - Dependabot 38 | - Discussions 39 | - Enterprise 40 | - Feed 41 | - GHAS 42 | - Gists 43 | - GitHub Desktop 44 | - GitHub Education 45 | - Issues 46 | - Lists 47 | - Markdown 48 | - Mobile 49 | - Notifications 50 | - Packages 51 | - Pages 52 | - Profile 53 | - Projects 54 | - Pull Requests 55 | - Repositories 56 | - Security and Privacy 57 | - Sponsors 58 | - UI/UX 59 | - Visual Studio 60 | - VSCode 61 | - Wiki 62 | - Other 63 | validations: 64 | required: true 65 | - type: textarea 66 | attributes: 67 | label: Body 68 | description: Start your discussion! 69 | validations: 70 | required: true 71 | -------------------------------------------------------------------------------- /.github/workflows/remove-governed-labels-on-label.yml: -------------------------------------------------------------------------------- 1 | name: 'On Label: Remove Governed Label' 2 | 3 | # Trigger workflow whenever a discussion is labeled 4 | on: 5 | discussion: 6 | types: [labeled] 7 | 8 | permissions: 9 | contents: read 10 | discussions: write 11 | 12 | jobs: 13 | action: 14 | runs-on: ubuntu-latest 15 | # Step 1 is to check if the user applying the label is an employee. If employee = 'true', later steps will not fire. If employee = 'false', later steps will continue 16 | steps: 17 | - name: Check if employee 18 | id: check_employee 19 | uses: actions/github-script@v7 20 | with: 21 | github-token: ${{ secrets.READ_GITHUB_ORG_MEMBERS_TOKEN }} 22 | result-encoding: string 23 | script: | 24 | try { 25 | const response = await github.rest.orgs.checkMembershipForUser({ 26 | org: `github`, 27 | username: context.payload.sender.login 28 | }); 29 | 30 | if (response.status === 204) { 31 | return 'true'; 32 | } else { 33 | return 'false'; 34 | } 35 | } catch (error) { 36 | console.log(error); 37 | return 'false'; 38 | } 39 | 40 | # Step 2 is to record the discussion id of the discussion that triggered the workflow in the GITHUB_ENV so the workflow knows which discussion post to then act on later 41 | - name: Fetch discussion ID 42 | id: fetch_discussion_id 43 | if: ${{ steps.check_employee.outputs.result == 'false' && github.event.repository && github.event.discussion }} 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | OWNER: ${{ github.repository_owner }} 47 | REPO: ${{ github.event.repository.name }} 48 | run: | 49 | gh api graphql -F owner=$OWNER -F name=$REPO -f query=' 50 | query($owner: String!, $name: String!) { 51 | repository(owner: $owner, name: $name) { 52 | discussion(number: ${{ github.event.discussion.number }}) { 53 | id 54 | } 55 | } 56 | }' > discussion_data.json 57 | 58 | echo 'DISCUSSION_ID='$(jq '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV 59 | 60 | # Step 3 references the label-actions.yml file for instructions. That config file tells the action what to do next. 61 | # config file will reference the GITHUB_ENV and will only process the 'unlabel' action on 'discussions' and will unlabel the named labels 62 | - name: Label Actions 63 | if: ${{ steps.check_employee.outputs.result == 'false' }} 64 | env: 65 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 66 | OWNER: ${{ github.repository_owner }} 67 | REPO: ${{ github.event.repository.name }} 68 | config-path: '.github/label-actions.yml' 69 | process-only: 'discussions' 70 | uses: dessant/label-actions@v3 71 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/actions.yml: -------------------------------------------------------------------------------- 1 | labels: [Actions] 2 | body: 3 | - type: markdown 4 | attributes: 5 | value: | 6 | 🚀 **Welcome to the Actions Category!** 🚀 7 | 8 | Automate, customize, and execute your software development workflows right in your repository with [GitHub Actions](https://docs.github.com/en/actions)! 9 | 10 | **Why are you here?** 11 | - **Have a Question?** Maybe you're stuck on workflow syntax, curious about best practices, or want to know how to use a specific GitHub Actions feature. Select "Question" to get help from the community! 12 | - **Product Feedback?** Do you have ideas to improve GitHub Actions, or want to share what works (or doesn't) for you? Select "Product Feedback" to help shape the future of GitHub Actions. 13 | - **Found a Bug?** If something isn't working as expected, let us know by selecting "Bug" so we can investigate and improve the platform. 14 | 15 | After choosing your reason, pick the topic or product area that best matches your discussion. 16 | 17 | **Quick links:** [Actions Documentation](https://docs.github.com/en/actions), [Workflow Syntax Guide](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions), [Example Workflows](https://docs.github.com/en/actions/use-cases-and-examples), and [Security Best Practices](https://docs.github.com/en/actions/security-for-github-actions) 18 | 19 | **Recent News:** 20 | - [Latest Breaking Changes](https://github.blog/changelog/label/actions) 21 | 22 | - type: dropdown 23 | id: reason 24 | attributes: 25 | label: Why are you starting this discussion? 26 | description: Tell us your goal! Are you asking a question, giving feedback, reporting a bug, or sharing something cool? 27 | options: 28 | - "Question" 29 | - "Product Feedback" 30 | - "Bug" 31 | default: 0 32 | validations: 33 | required: true 34 | - type: dropdown 35 | id: topic 36 | attributes: 37 | label: What GitHub Actions topic or product is this about? 38 | description: | 39 | Choose the single topic or product area most relevant to your discussion - [here is a list of label descriptions to help you decide which option fits best.](https://github.com/community/community/issues/labels?q=Action) 40 | 41 | If your post covers additional themes or topics, don't worry! Our team and automation will do our best to add extra labels based on the content of your discussion details. 42 | 43 | This helps us get you the best answers and feedback! 44 | options: 45 | - "ARC (Actions Runner Controller)" 46 | - "Actions Runner Image" 47 | - "Actions Runner" 48 | - "Actions Checkout" 49 | - "Actions Cache" 50 | - "General" 51 | - "Metrics & Insights" 52 | - "Workflow Deployment" 53 | - "Workflow Configuration" 54 | - "Schedule & Cron Jobs" 55 | default: 5 56 | validations: 57 | required: false 58 | - type: textarea 59 | attributes: 60 | label: Discussion Details 61 | description: >- 62 | Share your question, feedback, or story! Include links, code, or screenshots for more context. Tip: Reference the docs https://docs.github.com/en/actions or relevant changelogs for details. 63 | validations: 64 | required: true 65 | -------------------------------------------------------------------------------- /.github/DISCUSSION_TEMPLATE/github-education.yml: -------------------------------------------------------------------------------- 1 | body: 2 | - type: markdown 3 | attributes: 4 | value: | 5 | #### Welcome! Before You Create a New Post... 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Please read the **hints and tips** below. Your question might already have an answer waiting for you! 10 | If you are new here and are unsure where to start, please check out our [Quick Start Guide](https://github.com/orgs/community/discussions/141947). 👈 11 | - type: markdown 12 | attributes: 13 | value: | 14 | ### Let's first see if you need to create a discussion 🧠🔮 _We will attempt to read your mind..._ 15 | - **"Where are my academic benefits?"** Do you have this approved status image? You'll usually receive your benefits after 3 days of this approval status. Patience, my friend, patience! 😎 **"Awesome. But it's been 5 days?"** 😅 If you haven’t received your benefits within 5 days of your approval status, then yes, create this discussion and we'll assist! 16 | - **Check out our [SDP FAQ](https://gh.io/sdp-faq-nd) and [Educators FAQ](https://github.com/orgs/community/discussions/145312)** – It has the most commonly asked questions when applying including: 17 | * ⏱️ [How long after I’ve been approved will I receive my academic benefits?](https://gh.io/faq-nd-long) 18 | * 📩 [I don't have a school-issued email address, what other official proof of enrollment is accepted?](https://github.com/orgs/community/discussions/111352#i-dont-have-a-school-issued-email-address) 19 | * ✈️ 💻 [How to enable Copilot Pro for GitHub Education verified students/teachers?](https://gh.io/faq-nd-copilot) 20 | ### Thanks, but I still want to join the conversation! 💬😄 _Love it! We're here for the banter_ 21 | - **Can’t find your answer in our [SDP FAQ](https://gh.io/sdp-faq-nd)?** Then provide as much relevant information about your application as possible including posting your latest rejection reasons. 22 | - **Calling all verified Educators** 📣 Did you know we have an exclusive teachers only discussions board you can access after being verified? 🤫 [Check it out here](https://github.com/community/Global-Campus-Teachers/discussions?new-dis) 👈 23 | 24 | Once you're ready to post, feel free to jump in. **We’re here to help!** 🌟 Ensure you have read our [Code of Conduct](https://github.com/community/community/blob/main/CODE_OF_CONDUCT.md). Remember **do not post** any personal information on the discussions boards e.g images of your evidence. 25 | - type: textarea 26 | id: conversation 27 | attributes: 28 | label: Hi everyone, 29 | description: 30 | validations: 31 | required: true 32 | - type: markdown 33 | attributes: 34 | value: | 35 | #### Anything else I could do to make my experience here more rewarding? 🤔 36 | * Remember to mark an [answer as "solved"](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#marking-a-comment-as-an-answer) to help others with similar questions. ✅ 37 | * Praise generously 💖 Thank members who have helped you and continue to support others within the community. ✨ 38 | -------------------------------------------------------------------------------- /docs/Meet the Maintainers Sweepstakes Rules.md: -------------------------------------------------------------------------------- 1 | ### Meet the Maintainers March 2025 Random Prize Draw Terms and Conditions 2 | 3 | **1. Promoter** 4 | The promoter of this prize draw is GitHub Community, a division of GitHub, Inc., located at 88 Colin P. Kelly Jr. Street, San Francisco, CA 94107, USA. 5 | 6 | **2. Eligibility** 7 | 8 | The prize draw is open to verified registered GitHub users who are at least 13 years old. 9 | - Employees of GitHub, Microsoft, their immediate families, and anyone otherwise connected with the organization are not eligible to enter. 10 | - Participants under 18 years must have parental or guardian consent to enter. 11 | - The prize draw is void in countries where such promotions are prohibited by law. This includes, but is not limited to, the following countries: 12 | - Belgium 13 | - Poland 14 | - Malaysia 15 | - Brunei 16 | - Bangladesh 17 | - Italy 18 | - Any other country where local laws prohibit free entry random prize draws 19 | 20 | **3. Entry Period** 21 | 22 | - The entry period begins on March 11, 2025 11:59 PM EST and ends on March 18, 2025, at 11:59 PM EST. 23 | 24 | **4. How to Enter** 25 | 26 | - To enter, participants must visit the designated forum discussion and ask a question. 27 | - Entries must be original and not generated entirely by AI tools. AI tools may be used for grammar and spelling checks only. 28 | 29 | **5. Free Entry** 30 | 31 | - Participation in the prize draw is free, and no purchase is necessary to enter or win. 32 | 33 | **6. Parental/Guardian Consent** 34 | 35 | - If you are under 18 years old, you must have parental or guardian consent to enter the prize draw. By entering, you confirm that you have obtained such consent. 36 | 37 | **7. Selection of Winners** 38 | 39 | - Up to 5 winners will be selected at random from all eligible entries between March 11 and March 18, 2025. 40 | - The draw will be conducted using a verifiably random process under the supervision of an independent person or by an independent entity. 41 | 42 | **8. Notification of Winners** 43 | 44 | - Winners will be notified via the discussion by March 25, 2025. 45 | - Winners must fill out the form within 7 days to claim their prize. Failure to respond within this period may result in forfeiture of the prize, and GitHub Education reserves the right to select an alternative winner. 46 | 47 | **9. Prizes** 48 | 49 | - Each winner will receive a Github Shop voucher 50 | - Prizes are non-transferable and no cash alternative is available. 51 | - GitHub Community reserves the right to substitute any prize with another of equivalent value without giving notice. 52 | 53 | **10. Data Protection** 54 | 55 | - Participants’ personal data will be used solely for the purposes of administering the prize draw and in accordance with GitHub’s privacy policy. 56 | 57 | **11. General Conditions** 58 | 59 | - GitHub Community reserves the right to cancel or amend the prize draw and these terms and conditions without notice in the event of a catastrophe, war, civil or military disturbance, or any actual or anticipated breach of any applicable law or regulation or any other event outside GitHub Education’s control. 60 | - GitHub Community is not responsible for inaccurate prize details supplied to any participant by any third party connected with this prize draw. 61 | 62 | **12. Governing Law** 63 | 64 | - This prize draw and these terms and conditions will be governed by the laws of the country where the participant resides, provided that such laws do not conflict with the laws of the United States. Any disputes will be subject to the non-exclusive jurisdiction of the courts of the country of the participant’s residence. 65 | 66 | **13. Limitation of Liability** 67 | 68 | - By entering, participants agree to release and hold harmless GitHub Community, GitHub, Inc., and Microsoft from any liability, illness, injury, death, loss, litigation, claim, or damage that may occur, directly or indirectly, whether caused by negligence or not, from such entrant’s participation in the prize draw and/or their acceptance, possession, use, or misuse of any prize or any portion thereof. 69 | 70 | **14. Sponsor** 71 | 72 | - The prize draw is sponsored by GitHub Community. 73 | 74 | For further information or any questions regarding the prize draw, please contact [queenofcorgis@github.com]. 75 | -------------------------------------------------------------------------------- /docs/Accessibility Skills Student Series Spring 2025.md: -------------------------------------------------------------------------------- 1 | ### Accessibility Skills Student Series Spring 2025 Random Prize Draw Terms and Conditions 2 | 3 | **1. Promoter** 4 | The promoter of this prize draw is GitHub Education, a division of GitHub, Inc., located at 88 Colin P. Kelly Jr. Street, San Francisco, CA 94107, USA. 5 | 6 | **2. Eligibility** 7 | 8 | The prize draw is open to verified registered students of GitHub Education who are at least 13 years old. 9 | - Participants under 18 years must have parental or guardian consent to enter. 10 | - Employees of GitHub, Microsoft, their immediate families, and anyone otherwise connected with the organization are not eligible to enter. 11 | - The prize draw is void in countries where such promotions are prohibited by law. This includes, but is not limited to, the following countries: 12 | - Belgium 13 | - Poland 14 | - Malaysia 15 | - Brunei 16 | - Bangladesh 17 | - Italy 18 | - Any other country where local laws prohibit free entry random prize draws 19 | 20 | **3. Entry Period** 21 | 22 | - The entry period begins on April 14, 2025, 11:59 PM EST and ends on May 15, 2025, at 11:59 PM EST. 23 | 24 | **4. How to Enter** 25 | 26 | - To to receive an entry, participants must visit the designated forum discussion and complete the challenge for that week 27 | 28 | **5. Free Entry** 29 | 30 | - Participation in the prize draw is free, and no purchase is necessary to enter or win. 31 | 32 | **6. Parental/Guardian Consent** 33 | 34 | - If you are under 18 years old, you must have parental or guardian consent to enter the prize draw. By entering, you confirm that you have obtained such consent. 35 | 36 | **7. Selection of Winners** 37 | 38 | - Up to 10 winners will be selected at random from all eligible entries between May 15 and May 22, 2025. 39 | - The draw will be conducted using a verifiably random process under the supervision of an independent person or by an independent entity. 40 | 41 | **8. Notification of Winners** 42 | 43 | - Winners will be notified via the email associated with their GitHub account by May 31, 2025. 44 | - Winners must respond to the notification within 7 days to claim their prize. Failure to respond within this period may result in forfeiture of the prize, and GitHub Education reserves the right to select an alternative winner. 45 | 46 | **9. Prizes** 47 | 48 | - Each winner will receive GitHub swag, which may include items such as T-shirts, stickers, or other branded merchandise. 49 | - Prizes are non-transferable and no cash alternative is available. 50 | - GitHub Education reserves the right to substitute any prize with another of equivalent value without giving notice. 51 | 52 | **10. Data Protection** 53 | 54 | - Participants’ personal data will be used solely for the purposes of administering the prize draw and in accordance with GitHub’s privacy policy. 55 | 56 | **11. General Conditions** 57 | 58 | - GitHub Education reserves the right to cancel or amend the prize draw and these terms and conditions without notice in the event of a catastrophe, war, civil or military disturbance, or any actual or anticipated breach of any applicable law or regulation or any other event outside GitHub Education’s control. 59 | - GitHub Education is not responsible for inaccurate prize details supplied to any participant by any third party connected with this prize draw. 60 | 61 | **12. Governing Law** 62 | 63 | - This prize draw and these terms and conditions will be governed by the laws of the country where the participant resides, provided that such laws do not conflict with the laws of the United States. Any disputes will be subject to the non-exclusive jurisdiction of the courts of the country of the participant’s residence. 64 | 65 | **13. Limitation of Liability** 66 | 67 | - By entering, participants agree to release and hold harmless GitHub Education, GitHub, Inc., and Microsoft from any liability, illness, injury, death, loss, litigation, claim, or damage that may occur, directly or indirectly, whether caused by negligence or not, from such entrant’s participation in the prize draw and/or their acceptance, possession, use, or misuse of any prize or any portion thereof. 68 | 69 | **14. Sponsor** 70 | 71 | - The prize draw is sponsored by GitHub Education. 72 | 73 | For further information or any questions regarding the prize draw, please contact [morganersery1@github.com]. 74 | -------------------------------------------------------------------------------- /.github/workflows/issue_projects_labeler.yml: -------------------------------------------------------------------------------- 1 | name: Issue and Project Templated Discussions 2 | 3 | on: 4 | discussion: 5 | types: [created] 6 | 7 | jobs: 8 | label-templated-discussion: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Get discussion body html 13 | id: get_discussion_body_html 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | OWNER: ${{ github.repository_owner }} 17 | REPO: ${{ github.event.repository.name }} 18 | DISCUSSION_NUMBER: ${{ github.event.discussion.number }} 19 | run: | 20 | gh api graphql -F owner=$OWNER -F name=$REPO -F number=$DISCUSSION_NUMBER -f query=' 21 | query($owner: String!, $name: String!, $number: Int!) { 22 | repository(owner: $owner, name: $name){ 23 | discussion(number: $number) { 24 | bodyHTML 25 | id 26 | } 27 | } 28 | }' > discussion_data.json 29 | 30 | echo 'DISCUSSION_BODY_HTML='$(jq '.data.repository.discussion.bodyHTML' discussion_data.json) >> $GITHUB_ENV 31 | echo 'DISCUSSION_ID='$(jq '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV 32 | 33 | - run: npm install jsdom 34 | 35 | - name: Get selected topic 36 | id: get_selected_topic 37 | uses: actions/github-script@v7 38 | with: 39 | result-encoding: string 40 | script: | 41 | try { 42 | const jsdom = require('jsdom'); 43 | const { JSDOM } = jsdom; 44 | const { DISCUSSION_BODY_HTML } = process.env 45 | 46 | const fragment = JSDOM.fragment(DISCUSSION_BODY_HTML); 47 | const featureAreaHeaders = fragment.querySelectorAll("h3"); 48 | const featureAreaHeader = Array.from(featureAreaHeaders).find(header => header.textContent.trim().toLowerCase() === 'feature area'); 49 | if (!featureAreaHeader) { 50 | return ""; 51 | } 52 | 53 | const selectedTopicElement = featureAreaHeader.nextElementSibling; 54 | if (!selectedTopicElement) { 55 | return ""; 56 | } 57 | 58 | const selectedTopic = selectedTopicElement.textContent.trim().toLowerCase(); 59 | const validTopics = ["projects", "issues"]; 60 | return validTopics.includes(selectedTopic) ? selectedTopic : ""; 61 | 62 | } catch (error) { 63 | return ""; 64 | } 65 | 66 | - name: Fetch label id for selected topic 67 | id: fetch_label_id 68 | if: ${{ steps.get_selected_topic.outputs.result != '' }} 69 | env: 70 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | OWNER: ${{ github.repository_owner }} 72 | REPO: ${{ github.event.repository.name }} 73 | TOPIC: ${{ steps.get_selected_topic.outputs.result }} 74 | run: | 75 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$TOPIC" -f query=' 76 | query($owner: String!, $name: String!, $topic: String) { 77 | repository(owner: $owner, name: $name){ 78 | labels(first: 1, query: $topic) { 79 | edges { 80 | node { 81 | id 82 | name 83 | } 84 | } 85 | } 86 | } 87 | }' > repository_label_data.json 88 | 89 | echo 'LABEL_ID='$(jq '.data.repository.labels.edges[].node | .id ' repository_label_data.json) >> $GITHUB_ENV 90 | 91 | - name: Label the discussion 92 | if: ${{ steps.get_selected_topic.outputs.result != '' }} 93 | env: 94 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 95 | run: | 96 | gh api graphql -f query=' 97 | mutation($labelableId: ID!, $labelIds: [ID!]!) { 98 | addLabelsToLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) { 99 | labelable { 100 | labels(first: 10) { 101 | edges { 102 | node { 103 | id 104 | name 105 | } 106 | } 107 | } 108 | } 109 | } 110 | }' -f labelableId=$DISCUSSION_ID -f labelIds=$LABEL_ID 111 | -------------------------------------------------------------------------------- /.github/workflows/label-templated-discussions.yml: -------------------------------------------------------------------------------- 1 | name: Label Templated Discussions 2 | 3 | on: 4 | discussion: 5 | types: [created] 6 | 7 | jobs: 8 | label-templated-discussion: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Get discussion body html 13 | id: get_discussion_body_html 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | OWNER: ${{ github.repository_owner }} 17 | REPO: ${{ github.event.repository.name }} 18 | DISCUSSION_NUMBER: ${{ github.event.discussion.number }} 19 | run: | 20 | gh api graphql -F owner=$OWNER -F name=$REPO -F number=$DISCUSSION_NUMBER -f query=' 21 | query($owner: String!, $name: String!, $number: Int!) { 22 | repository(owner: $owner, name: $name){ 23 | discussion(number: $number) { 24 | bodyHTML 25 | id 26 | } 27 | } 28 | }' > discussion_data.json 29 | 30 | echo 'DISCUSSION_BODY_HTML='$(jq '.data.repository.discussion.bodyHTML' discussion_data.json) >> $GITHUB_ENV 31 | echo 'DISCUSSION_ID='$(jq '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV 32 | 33 | - run: npm install jsdom 34 | 35 | - name: Get selected topic 36 | id: get_selected_topic 37 | uses: actions/github-script@v7 38 | with: 39 | result-encoding: string 40 | script: | 41 | try { 42 | const jsdom = require('jsdom'); 43 | const { JSDOM } = jsdom; 44 | const { DISCUSSION_BODY_HTML } = process.env 45 | 46 | const fragment = JSDOM.fragment(DISCUSSION_BODY_HTML); 47 | const selectTopicHeader = fragment.querySelector("h3"); 48 | const templated = selectTopicHeader.textContent === 'Select Topic Area'; 49 | if (!templated) { 50 | return ""; 51 | } 52 | 53 | const selectedTopicElement = selectTopicHeader.nextElementSibling; 54 | if (!selectedTopicElement) { 55 | return ""; 56 | } 57 | 58 | const selectedTopic = selectedTopicElement.textContent.trim().toLowerCase(); 59 | const validTopics = ["product feedback", "question", "bug", "show & tell", "general"]; 60 | return validTopics.includes(selectedTopic) ? selectedTopic : ""; 61 | 62 | } catch (error) { 63 | return ""; 64 | } 65 | 66 | - name: Fetch label id for selected topic 67 | id: fetch_label_id 68 | if: ${{ steps.get_selected_topic.outputs.result != '' }} 69 | env: 70 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | OWNER: ${{ github.repository_owner }} 72 | REPO: ${{ github.event.repository.name }} 73 | TOPIC: ${{ steps.get_selected_topic.outputs.result }} 74 | run: | 75 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$TOPIC" -f query=' 76 | query($owner: String!, $name: String!, $topic: String) { 77 | repository(owner: $owner, name: $name){ 78 | labels(first: 1, query: $topic) { 79 | edges { 80 | node { 81 | id 82 | name 83 | } 84 | } 85 | } 86 | } 87 | }' > repository_label_data.json 88 | 89 | echo 'LABEL_ID='$(jq '.data.repository.labels.edges[].node | .id ' repository_label_data.json) >> $GITHUB_ENV 90 | 91 | - name: Label the discussion 92 | if: ${{ steps.get_selected_topic.outputs.result != '' }} 93 | env: 94 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 95 | run: | 96 | gh api graphql -f query=' 97 | mutation($labelableId: ID!, $labelIds: [ID!]!) { 98 | addLabelsToLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) { 99 | labelable { 100 | labels(first: 10) { 101 | edges { 102 | node { 103 | id 104 | name 105 | } 106 | } 107 | } 108 | } 109 | } 110 | }' -f labelableId=$DISCUSSION_ID -f labelIds=$LABEL_ID 111 | 112 | -------------------------------------------------------------------------------- /.github/workflows/remove-governed-labels-on-create.yml: -------------------------------------------------------------------------------- 1 | name: 'On Create: Remove Governed Label' 2 | 3 | # Trigger workflow whenever a discussion is created 4 | on: 5 | discussion: 6 | types: [created] 7 | 8 | jobs: 9 | check_labels: 10 | name: Check labels 11 | runs-on: ubuntu-latest 12 | 13 | # Step 1 is to check if the discussion creator is an employee. If employee = 'true', later steps will not fire. If employee = 'false', later steps will continue 14 | steps: 15 | - name: Check if employee 16 | id: check_employee 17 | uses: actions/github-script@v7 18 | with: 19 | github-token: ${{ secrets.READ_GITHUB_ORG_MEMBERS_TOKEN }} 20 | result-encoding: string 21 | script: | 22 | console.log(context.payload); 23 | 24 | try { 25 | const response = await github.rest.orgs.checkMembershipForUser({ 26 | org: `github`, 27 | username: context.payload.sender.login 28 | }); 29 | 30 | if (response.status === 204) { 31 | return 'true'; 32 | } else { 33 | return 'false'; 34 | } 35 | } catch (error) { 36 | console.log(error); 37 | return 'false'; 38 | } 39 | 40 | # Step 2 grabs the label id of the label we want to remove and stores it in the GITHUB_ENV. We use the 'TOPIC' to define the label in plain text 41 | - name: Fetch label id 42 | id: fetch_label_id 43 | if: ${{ steps.check_employee.outputs.result == 'false' }} 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | OWNER: ${{ github.repository_owner }} 47 | REPO: ${{ github.event.repository.name }} 48 | TOPIC: 'more information needed' 49 | run: | 50 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$TOPIC" -f query=' 51 | query($owner: String!, $name: String!, $topic: String) { 52 | repository(owner: $owner, name: $name){ 53 | labels(first: 3, query: $topic) { 54 | edges { 55 | node { 56 | id 57 | name 58 | } 59 | } 60 | } 61 | } 62 | }' > repository_label_data.json 63 | 64 | echo 'LABEL_ID='$(jq '.data.repository.labels.edges[].node | .id ' repository_label_data.json) >> $GITHUB_ENV 65 | 66 | # Step 3 is to record the discussion id of the discussion that triggered the workflow in the GITHUB_ENV so the workflow knows which discussion post to then act on later 67 | - name: Fetch discussion ID 68 | id: fetch_discussion_id 69 | if: ${{ steps.check_employee.outputs.result == 'false' }} 70 | env: 71 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 72 | OWNER: ${{ github.repository_owner }} 73 | REPO: ${{ github.event.repository.name }} 74 | TOPIC: 'more information needed' 75 | run: | 76 | gh api graphql -F owner=$OWNER -F name=$REPO -f query=' 77 | query($owner: String!, $name: String!) { 78 | repository(owner: $owner, name: $name) { 79 | discussion(number: ${{ github.event.discussion.number }}) { 80 | id 81 | } 82 | } 83 | }' > discussion_data.json 84 | 85 | echo 'DISCUSSION_ID='$(jq '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV 86 | 87 | # Step 4 recalls the appropriate discussion id and label id from the GITHUB_ENV and removes the label from the discussion 88 | - name: Unlabel the discussion 89 | env: 90 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 91 | OWNER: ${{ github.repository_owner }} 92 | REPO: ${{ github.event.repository.name }} 93 | DISCUSSION_ID: ${{ env.DISCUSSION_ID }} 94 | LABEL_IDS: ${{ env.LABEL_ID }} 95 | run: | 96 | IFS=' ' read -ra labelIds <<< "$LABEL_IDS" 97 | for labelId in "${labelIds[@]}"; do 98 | gh api graphql -f query=' 99 | mutation($labelableId: ID!, $labelIds: [ID!]!) { 100 | removeLabelsFromLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) { 101 | labelable { 102 | labels(first: 10) { 103 | edges { 104 | node { 105 | id 106 | name 107 | } 108 | } 109 | } 110 | } 111 | } 112 | }' -f labelableId=$DISCUSSION_ID -f labelIds=$labelId 113 | done 114 | -------------------------------------------------------------------------------- /.github/workflows/recategorize-discussions.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow that is manually triggered 2 | 3 | name: Recategorize labeled discussions 4 | 5 | # Controls when the action will run. Workflow runs when manually triggered using the UI 6 | # or API. 7 | on: 8 | workflow_dispatch: 9 | # Inputs the workflow accepts. 10 | inputs: 11 | label: 12 | # Friendly description to be shown in the UI instead of 'name' 13 | description: 'Label for discussions that will be recategorized' 14 | # Default value if no value is explicitly provided 15 | default: 'bug' 16 | # Input has to be provided for the workflow to run 17 | required: true 18 | # The data type of the input 19 | type: string 20 | category: 21 | # Friendly description to be shown in the UI instead of 'name' 22 | description: 'The name of the category the labeled discussions will be moved to' 23 | # Default value if no value is explicitly provided 24 | default: 'Ideas' 25 | # Input has to be provided for the workflow to run 26 | required: true 27 | # The data type of the input 28 | type: string 29 | max_to_move: 30 | description: 'The maximum number of discussions we should try to move (up to 100), helpful in testing' 31 | type: number 32 | default: 50 33 | required: true 34 | 35 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 36 | jobs: 37 | # This workflow contains a single job called "greet" 38 | recategorize-discussions: 39 | # The type of runner that the job will run on 40 | runs-on: ubuntu-latest 41 | 42 | # Steps represent a sequence of tasks that will be executed as part of the job 43 | steps: 44 | # Runs a single command using the runners shell 45 | - name: Send greeting 46 | run: echo "Moving Discussions labeled ${{ inputs.label }} to category ${{ inputs.category }}" 47 | # Use the graphql search api to find all discussions with the label using the search() query 48 | - name: Find labeled discussions 49 | env: 50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 51 | run: | 52 | searchQuery="label:\"${{ inputs.label }}\" repo:${{ github.repository}} -category:\"${{ inputs.category }}\"" 53 | discussions="$(gh api graphql -F queryString="$searchQuery" -f query=' 54 | query($queryString: String!) { 55 | search(query:$queryString,type:DISCUSSION,first:${{ inputs.max_to_move }}){ 56 | nodes{ 57 | ...on Discussion{id} 58 | } 59 | } 60 | }' | jq -r '.data.search.nodes[].id')" 61 | echo 'Found discussions: '"$discussions" 62 | echo 'DISCUSSIONS_TO_TRANSFER='$discussions >> $GITHUB_ENV 63 | - name: Find the id of the discussion category in the current repository 64 | env: 65 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 66 | run: | 67 | # split github.repository into owner and name 68 | repoName=$(echo ${{ github.repository }} | cut -d '/' -f 2) 69 | found_category=$(gh api graphql -F name="$repoName" -F owner="${{ github.repository_owner }}" -f query=' 70 | query($name: String!, $owner: String!){ 71 | repository(owner:$owner, name:$name){ 72 | discussionCategories(first:100){ 73 | nodes{ 74 | id 75 | name 76 | } 77 | } 78 | } 79 | }' | jq -r --arg category "${{ inputs.category }}" '.data.repository.discussionCategories.nodes[] | select(.name==$category) | .id') 80 | echo 'CATEGORY_ID='$found_category >> $GITHUB_ENV 81 | - name: Dryrun 82 | env: 83 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 84 | run: | 85 | echo "Dryrun" 86 | echo "DISCUSSIONS_TO_TRANSFER=$DISCUSSIONS_TO_TRANSFER" 87 | echo "CATEGORY_ID=$CATEGORY_ID" 88 | - name: Move discussions 89 | env: 90 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 91 | run: | 92 | # DISCUSSIONS_TO_TRANSFER is in the form "id_1 id_2 id_3" 93 | # Loop over the ids and use the updateDiscussion mutation to move the discussion to the new category 94 | for discussion_id in $DISCUSSIONS_TO_TRANSFER; do 95 | echo "Moving discussion $discussion_id to category $CATEGORY_ID" 96 | gh api graphql -F discussionId="$discussion_id" -F categoryId="$CATEGORY_ID" -f query=' 97 | mutation($discussionId: ID!, $categoryId: ID!) { 98 | updateDiscussion(input: {discussionId: $discussionId, categoryId: $categoryId}) { 99 | discussion { 100 | number 101 | } 102 | } 103 | }' 104 | done 105 | -------------------------------------------------------------------------------- /.github/workflows/Accessibility-Labeler.yml: -------------------------------------------------------------------------------- 1 | name: Accessibility Templated Discussions 2 | 3 | on: 4 | discussion: 5 | types: [created] 6 | 7 | jobs: 8 | label-templated-discussion: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Get discussion body html 13 | id: get_discussion_body_html 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | OWNER: ${{ github.repository_owner }} 17 | REPO: ${{ github.event.repository.name }} 18 | DISCUSSION_NUMBER: ${{ github.event.discussion.number }} 19 | run: | 20 | gh api graphql -F owner=$OWNER -F name=$REPO -F number=$DISCUSSION_NUMBER -f query=' 21 | query($owner: String!, $name: String!, $number: Int!) { 22 | repository(owner: $owner, name: $name){ 23 | discussion(number: $number) { 24 | bodyHTML 25 | id 26 | } 27 | } 28 | }' > discussion_data.json 29 | 30 | echo 'DISCUSSION_BODY_HTML='$(jq '.data.repository.discussion.bodyHTML' discussion_data.json) >> $GITHUB_ENV 31 | echo 'DISCUSSION_ID='$(jq '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV 32 | 33 | - run: npm install jsdom 34 | 35 | - name: Get selected topic 36 | id: get_selected_topic 37 | uses: actions/github-script@v7 38 | with: 39 | result-encoding: string 40 | script: | 41 | try { 42 | const jsdom = require('jsdom'); 43 | const { JSDOM } = jsdom; 44 | const { DISCUSSION_BODY_HTML } = process.env 45 | 46 | const fragment = JSDOM.fragment(DISCUSSION_BODY_HTML); 47 | const featureAreaHeaders = fragment.querySelectorAll("h3"); 48 | const featureAreaHeader = Array.from(featureAreaHeaders).find(header => header.textContent.trim().toLowerCase() === 'github feature area'); 49 | if (!featureAreaHeader) { 50 | return ""; 51 | } 52 | 53 | const selectedTopicElement = featureAreaHeader.nextElementSibling; 54 | if (!selectedTopicElement) { 55 | return ""; 56 | } 57 | 58 | const selectedTopic = selectedTopicElement.textContent.trim().toLowerCase(); 59 | const validTopics = ["actions", "apis and webhooks", "code scanning", "code search and navigation", "code security", "codespaces", "command palette", "copilot", "dependabot", "discussions", "enterprise", "feed", "ghas", "gists", "github desktop", "github education", "issues", "lists", "markdown", "mobile", "notifications", "packages", "pages", "profile", "projects", "pull requests", "repositories", "security and privacy", "sponsors", "ui/ux", "visual studio", "vscode", "wiki"]; 60 | return validTopics.includes(selectedTopic) ? selectedTopic : ""; 61 | 62 | } catch (error) { 63 | return ""; 64 | } 65 | 66 | - name: Fetch label id for selected topic 67 | id: fetch_label_id 68 | if: ${{ steps.get_selected_topic.outputs.result != '' }} 69 | env: 70 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | OWNER: ${{ github.repository_owner }} 72 | REPO: ${{ github.event.repository.name }} 73 | TOPIC: ${{ steps.get_selected_topic.outputs.result }} 74 | run: | 75 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$TOPIC" -f query=' 76 | query($owner: String!, $name: String!, $topic: String) { 77 | repository(owner: $owner, name: $name){ 78 | labels(first: 1, query: $topic) { 79 | edges { 80 | node { 81 | id 82 | name 83 | } 84 | } 85 | } 86 | } 87 | }' > repository_label_data.json 88 | 89 | echo 'LABEL_ID='$(jq '.data.repository.labels.edges[].node | .id ' repository_label_data.json) >> $GITHUB_ENV 90 | 91 | - name: Label the discussion 92 | if: ${{ steps.get_selected_topic.outputs.result != '' }} 93 | env: 94 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 95 | run: | 96 | gh api graphql -f query=' 97 | mutation($labelableId: ID!, $labelIds: [ID!]!) { 98 | addLabelsToLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) { 99 | labelable { 100 | labels(first: 10) { 101 | edges { 102 | node { 103 | id 104 | name 105 | } 106 | } 107 | } 108 | } 109 | } 110 | }' -f labelableId=$DISCUSSION_ID -f labelIds=$LABEL_ID 111 | -------------------------------------------------------------------------------- /docs/Spring 2025 GitHub Foundation Certification Prep Course Sweepstakes Official Rules.md: -------------------------------------------------------------------------------- 1 | # MICROSOFT SPRING 2025 GITHUB FOUNDATIONS CERTIFICATION PREP COURSE SWEEPSTAKES 2 | 3 | ## OFFICIAL RULES 4 | 5 | --- 6 | 7 | ## SPONSOR 8 | 9 | These Official Rules ("Rules") govern the operation of the Microsoft Spring 2025 GitHub Foundations Certification Prep Course Sweepstakes ("Sweepstakes"). Microsoft Corporation, One Microsoft Way, Redmond, WA, 98052, USA, is the Sweepstakes sponsor ("Sponsor"). 10 | 11 | --- 12 | 13 | ## DEFINITIONS 14 | 15 | In these Rules, "Microsoft", "we", "our", and "us" refer to Sponsor and "you" and "yourself" refers to a Sweepstakes participant, or the parent/legal guardian of any Sweepstakes entrant who has not reached the age of majority to contractually obligate themselves in their legal place of residence. By entering you (your parent/legal guardian if you are not the age of majority in your legal place of residence) agree to be bound by these Rules. 16 | 17 | --- 18 | 19 | ## ENTRY PERIOD 20 | 21 | The Sweepstakes starts at **12:00 a.m. Pacific Time (PT) on March 31, 2025**, and ends at **11:59 p.m. PT on May 2, 2025** and will consist of five (5) weekly Entry Periods as follows (each an "Entry Period"): 22 | 23 | - **March 31, 2025, 12:00 a.m. PT – April 4, 2025, 11:59 p.m. PT** 24 | - **April 5, 2025, 12:00 a.m. PT – April 11, 2025, 11:59 p.m. PT** 25 | - **April 12, 2025, 12:00 a.m. PT – April 18, 2025, 11:59 p.m. PT** 26 | - **April 19, 2025, 12:00 a.m. PT – April 25, 2025, 11:59 p.m. PT** 27 | - **April 26, 2025, 12:00 a.m. PT – May 2, 2025, 11:59 p.m. PT** 28 | 29 | --- 30 | 31 | ## ELIGIBILITY 32 | 33 | To enter, you must be **14 years of age or older** with an **active GitHub account**. If you are 14 years of age or older but have not reached the age of majority in your legal place of residence, then you must have consent of a parent/legal guardian. 34 | 35 | **Not eligible:** Employees and directors of Microsoft Corporation, its subsidiaries, affiliates, advertising agencies, and Sweepstakes Parties. Void in Cuba, Iran, North Korea, Sudan, Syria, Region of Crimea, Russia, and where prohibited. 36 | 37 | --- 38 | 39 | ## HOW TO ENTER 40 | 41 | **No Purchase Necessary.** 42 | 43 | You will receive **one entry** by visiting the web site for the Sweepstakes at [GitHub Community Discussions](https://github.com/orgs/community/discussions/) and completing any of the following tasks: 44 | 45 | - Answer a knowledge check 46 | - Share resources 47 | - Ask questions 48 | - Create a study guide 49 | 50 | **Entry limit:** One per person per weekly Entry Period. 51 | 52 | Attempts to submit multiple entries using multiple accounts or automated methods will result in disqualification. 53 | 54 | --- 55 | 56 | ## WINNER SELECTION AND NOTIFICATION 57 | 58 | Pending confirmation of eligibility, **twenty-five (25) potential prize winners** will be selected by Microsoft or their Agent in a random drawing from among all eligible entries within **7 days** following the end of the Entry Period. 59 | 60 | Winners will be notified within **7 days** following the drawing. If a selected winner cannot be contacted, is ineligible, or fails to claim their prize, an alternate winner will be selected. A maximum of three alternate winners will be chosen before prizes go unawarded. 61 | 62 | --- 63 | 64 | ## PRIZES 65 | 66 | ### Twenty-Five (25) Grand Prizes 67 | 68 | Each winner will receive a **GitHub Certification voucher**. 69 | 70 | - **Approximate Retail Value (ARV):** $50.00 71 | - **Total ARV of all prizes:** $1,250 72 | 73 | Only one (1) prize per person overall. **No substitution, transfer, or assignment of prize permitted.** Microsoft reserves the right to substitute a prize of equal or greater value if the offered prize is unavailable. 74 | 75 | Prizes will be sent no later than **28 days after winner selection**. 76 | 77 | **Taxes on the prize are the sole responsibility of the winner.** By accepting a prize, you agree that Microsoft may use your entry, name, image, and hometown online and in print in connection with this Sweepstakes. 78 | 79 | --- 80 | 81 | ## ODDS 82 | 83 | The odds of winning depend on the number of eligible entries received. 84 | 85 | --- 86 | 87 | ## GENERAL CONDITIONS AND RELEASE OF LIABILITY 88 | 89 | To the extent allowed by law, by entering you agree to release and hold harmless **Microsoft**, its parents, partners, subsidiaries, affiliates, employees, and agents from any liability related to this Sweepstakes. 90 | 91 | Microsoft reserves the right to **cancel, change, or suspend** the Sweepstakes due to unforeseen circumstances affecting the integrity of the contest. 92 | 93 | If you attempt to **cheat, hack, or commit fraud**, Microsoft may disqualify you and seek damages. 94 | 95 | --- 96 | 97 | ## USE OF YOUR ENTRY 98 | 99 | Personal data provided while entering this Sweepstakes will be used **only for administration and operation** of this Sweepstakes in accordance with the [Microsoft Privacy Statement](https://privacy.microsoft.com/). 100 | 101 | --- 102 | 103 | ## GOVERNING LAW 104 | 105 | This Sweepstakes is governed by the **laws of the State of Washington**, and participants consent to the **exclusive jurisdiction and venue** of its courts for any disputes. 106 | 107 | --- 108 | 109 | ## WINNERS LIST 110 | 111 | To receive a list of winners, send an email to **lgalante@microsoft.com** with the subject line: 112 | 113 | > *Spring 2025 GitHub Foundations Certification Prep Course Sweepstakes winners* 114 | 115 | within **30 days of May 2, 2025**. 116 | -------------------------------------------------------------------------------- /.github/workflows/copilot_labeller.yml: -------------------------------------------------------------------------------- 1 | name: Copilot Templated Discussions 2 | 3 | on: 4 | discussion: 5 | types: [created] 6 | 7 | jobs: 8 | label-copilot-discussion: 9 | runs-on: ubuntu-latest 10 | if: ${{ contains(github.event.discussion.category.name, 'Copilot') }} 11 | 12 | steps: 13 | - name: Get discussion body html 14 | id: get_discussion_body_html 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | OWNER: ${{ github.repository_owner }} 18 | REPO: ${{ github.event.repository.name }} 19 | DISCUSSION_NUMBER: ${{ github.event.discussion.number }} 20 | run: | 21 | gh api graphql -F owner=$OWNER -F name=$REPO -F number=$DISCUSSION_NUMBER -f query=' 22 | query($owner: String!, $name: String!, $number: Int!) { 23 | repository(owner: $owner, name: $name){ 24 | discussion(number: $number) { 25 | bodyHTML 26 | id 27 | } 28 | } 29 | }' > discussion_data.json 30 | 31 | echo 'DISCUSSION_BODY_HTML='$(jq -r '.data.repository.discussion.bodyHTML' discussion_data.json) >> $GITHUB_ENV 32 | echo 'DISCUSSION_ID='$(jq -r '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV 33 | - run: npm install jsdom 34 | 35 | - name: Get selected Copilot feature area 36 | id: get_selected_feature_area 37 | uses: actions/github-script@v6 38 | with: 39 | result-encoding: string 40 | script: | 41 | try { 42 | const jsdom = require('jsdom'); 43 | const { JSDOM } = jsdom; 44 | const { DISCUSSION_BODY_HTML } = process.env 45 | 46 | const fragment = JSDOM.fragment(DISCUSSION_BODY_HTML); 47 | const featureAreaHeaders = fragment.querySelectorAll("h3"); 48 | const featureAreaHeader = Array.from(featureAreaHeaders).find(header => 49 | header.textContent.trim().toLowerCase().includes('copilot feature area')); 50 | if (!featureAreaHeader) { 51 | return ""; 52 | } 53 | 54 | const selectedAreaElement = featureAreaHeader.nextElementSibling; 55 | if (!selectedAreaElement) { 56 | return ""; 57 | } 58 | 59 | const selectedArea = selectedAreaElement.textContent.trim(); 60 | // Simplify area matching by converting to lowercase 61 | const selectedAreaLower = selectedArea.toLowerCase(); 62 | 63 | // Valid Copilot feature areas (case insensitive matching) 64 | const validAreas = { 65 | "vs code": "VS Code", 66 | "visual studio": "Visual Studio", 67 | "jetbrains & xcode": "JetBrains & Xcode", 68 | "copilot in github": "Copilot in GitHub", 69 | "copilot workspace": "Copilot Workspace", 70 | "copilot edits and code review": "Copilot Edits and Code Review", 71 | "copilot agent mode": "Copilot Agent Mode", 72 | "copilot coding agent": "Copilot Coding Agent", 73 | "copilot enterprise": "Copilot Enterprise", 74 | "copilot billing or account‑related": "Copilot Billing or Account‑Related", 75 | "other copilot areas": "Other Copilot Areas" 76 | }; 77 | 78 | // Try to find a matching area (case insensitive) 79 | for (const [key, value] of Object.entries(validAreas)) { 80 | if (selectedAreaLower.includes(key)) { 81 | return value; // Return the properly cased label 82 | } 83 | } 84 | 85 | // If no match found, check if it's exactly one of our valid areas 86 | // This helps with unexpected formatting or spacing 87 | if (selectedArea && Object.values(validAreas).includes(selectedArea)) { 88 | return selectedArea; 89 | } 90 | 91 | // Default to "Other Copilot Areas" if we can't find a specific match 92 | if (selectedArea) { 93 | return "Other Copilot Areas"; 94 | } 95 | 96 | return ""; 97 | } catch (error) { 98 | console.error(error); 99 | return ""; 100 | } 101 | 102 | - name: Fetch label id for selected area 103 | id: fetch_label_id 104 | if: ${{ steps.get_selected_feature_area.outputs.result != '' }} 105 | env: 106 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 107 | OWNER: ${{ github.repository_owner }} 108 | REPO: ${{ github.event.repository.name }} 109 | AREA: ${{ steps.get_selected_feature_area.outputs.result }} 110 | run: | 111 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$AREA" -f query=' 112 | query($owner: String!, $name: String!, $topic: String) { 113 | repository(owner: $owner, name: $name){ 114 | labels(first: 1, query: $topic) { 115 | edges { 116 | node { 117 | id 118 | name 119 | } 120 | } 121 | } 122 | } 123 | }' > repository_label_data.json 124 | 125 | LABEL_ID=$(jq -r '.data.repository.labels.edges[0]?.node?.id // empty' repository_label_data.json) 126 | if [ -z "$LABEL_ID" ]; then 127 | echo "No matching label found for the selected area. Skipping labeling step." 128 | fi 129 | echo "LABEL_ID=$LABEL_ID" >> $GITHUB_ENV 130 | 131 | - name: Label the discussion 132 | if: ${{ steps.get_selected_feature_area.outputs.result != '' && env.LABEL_ID != '' }} 133 | env: 134 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 135 | run: | 136 | gh api graphql -f query=' 137 | mutation($labelableId: ID!, $labelIds: [ID!]!) { 138 | addLabelsToLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) { 139 | labelable { 140 | labels(first: 10) { 141 | edges { 142 | node { 143 | id 144 | name 145 | } 146 | } 147 | } 148 | } 149 | } 150 | }' -f labelableId=$DISCUSSION_ID -f labelIds[]=$LABEL_ID 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GitHub Community Discussions 2 | 3 | In this repository, you will find categories for various product areas. Feel free to share feedback, discuss topics with other community members, or ask questions. 4 | 5 | ## Product Feedback 6 | 7 | | **Feedback Category** | **About the Product** | 8 | |--- |--- | 9 | | 👍 [Accessibility](https://github.com/orgs/community/discussions/categories/accessibility) | [About Accessibility](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-personal-account-settings/managing-accessibility-settings#about-accessibility-settings) | 10 | | 🚢 [Actions](https://github.com/orgs/community/discussions/categories/actions) | [GitHub Actions](https://github.com/features/actions) | 11 | | 🔁 [API and Webhooks](https://github.com/orgs/community/discussions/categories/api-and-webhooks) | [GitHub REST API](https://docs.github.com/en/rest), [GitHub GraphQL API](https://docs.github.com/en/graphql), and [GitHub Webhooks](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhook) | 12 | | 🔎 [Code Search & Navigation](https://github.com/orgs/community/discussions/categories/code-search-and-navigation) | [Code Search & Navigation](https://cs.github.com/about) | 13 | | 💻 [Codespaces](https://github.com/orgs/community/discussions/categories/codespaces) | [GitHub Codespaces](https://github.com/features/codespaces) | 14 | | :copilot: [Copilot Conversations](https://github.com/orgs/community/discussions/categories/copilot-conversations) | [GitHub Copilot](https://copilot.github.com/) | 15 | | 🤖 [Code Security](https://github.com/orgs/community/discussions/categories/code-security) | [GitHub Code Security](https://github.com/features/security) | 16 | | 🗣️ [Discussions](https://github.com/orgs/community/discussions/categories/discussions) | [GitHub Discussions](https://docs.github.com/en/discussions) | 17 | | 🌐 [Feed](https://github.com/orgs/community/discussions/categories/feed) | [GitHub Feed](https://github.blog/2022-03-22-improving-your-github-feed/) | 18 | | 🎒 [GitHub Education](https://github.com/orgs/community/discussions/categories/github-education) | [GitHub Education](https://education.github.com/) | 19 | | ⭐ [Lists](https://github.com/orgs/community/discussions/categories/lists) | [GitHub Lists](https://docs.github.com/en/get-started/exploring-projects-on-github/saving-repositories-with-stars#organizing-starred-repositories-with-lists) (Public Beta) | 20 | | 📱 [Mobile](https://github.com/orgs/community/discussions/categories/mobile) | [GitHub Mobile](https://github.com/mobile) | 21 | | 📦 [Packages](https://github.com/orgs/community/discussions/categories/packages) | [GitHub Packages](https://github.com/features/packages) | 22 | | 🗒️ [Pages](https://github.com/orgs/community/discussions/categories/pages) | [GitHub Pages](https://docs.github.com/en/pages) | 23 | | 🖼️ [Profile](https://github.com/orgs/community/discussions/categories/profile) | [GitHub Profile](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/about-your-profile) | 24 | | 🐙 [Projects and Issues](https://github.com/orgs/community/discussions/categories/projects-and-issues) | [GitHub Projects](https://docs.github.com/en/issues/planning-and-tracking-with-projects) / [GitHub Issues](https://github.com/features/issues) | 25 | | ✔️ [Pull Requests](https://github.com/orgs/community/discussions/categories/pull-requests) | [GitHub Pull Requests](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) | 26 | | 🗳️ [Repositories](https://github.com/orgs/community/discussions/categories/repositories) | [GitHub Repositories](https://docs.github.com/en/repositories) | 27 | | 💖 [Sponsors](https://github.com/orgs/community/discussions/categories/sponsors) | [GitHub Sponsors](https://github.com/sponsors) | 28 | | :octocat: [General Feedback](https://github.com/orgs/community/discussions/categories/general) | [GitHub Docs](https://docs.github.com/en) | 29 | 30 | These discussions are where you can share suggestions for how the products should be improved and discuss those improvements with the community, including members of the GitHub product team. Check out [Making suggestions](#making-suggestions) to learn how to provide feedback. 31 | 32 | ## Discussions Categories 33 | 34 | You will also find previous Discourse Community Forum categories that have since been updated in GitHub Discussions categories below: 35 | 36 | | **Discourse Category** | **New Discussions Category** | 37 | |--- |--- | 38 | | GitHub Help | New to GitHub | 39 | | Code to Cloud | Actions and Packages | 40 | | GitHub Ecosystem | APIs and Integrations | 41 | | Uncategorized | General | 42 | | Software Development | Programming Help | 43 | | | Machine Learning and ML Ops | 44 | 45 | When creating a new post, make sure to choose the predetermined category that best fits your topic. This will ensure that conversations are indexed by their corresponding product or feature, to help community members quickly find answers to their questions. 46 | 47 | This repository works in conjunction with the [GitHub public product roadmap](https://github.com/github/roadmap), which is where you can learn about what features we're working on, and when they'll be available. Accordingly, the Issues feature of this repository has been disabled. Discussion categories have been established for specific features listed above, as well as a general category for other topics. Additional categories may be added in the future. In the meantime, topics outside of the listed categories above, will be transferred into the General category. Please review the [CODE OF CONDUCT](https://docs.github.com/en/site-policy/github-terms/github-community-forum-code-of-conduct) before participating in discussions. 48 | 49 | ## Making suggestions 50 | 51 | We encourage you to [open a discussion](https://github.com/orgs/community/discussions) if you have suggestions for how we can improve our products. You don't need to have a solution to the problem you are facing to kick off a discussion. 52 | 53 | Prior to creating a new discussion, please take a look at previous discussions to see if someone else has already shared your suggestion(s). If you find a similar discussion, reply with additional details or upvote the discussion to signal your support rather than creating a new one. 54 | 55 | ### From a suggestion to a shipped feature 56 | 57 | Once you kick off a discussion, the GitHub product team will evaluate the feedback but will not be able to respond to every submission. From there, we will work with you, and the entire community, to ensure we understand the current capabilities GitHub doesn’t have and explore the space for potential solutions to your problem statement: 58 | 59 | - If the product team determines that we are going to prioritize a feature to solve the problem you've identified, we may open an issue and track its development in the [public roadmap](https://github.com/github/roadmap). 60 | - If the product team determines that we will not be working to solve the problem you have identified, we may comment on the discussion describing our reasoning so our decisions can remain transparent. 61 | 62 | ## Disclaimer 63 | 64 | Any statement in this repository that is not purely historical is considered a forward-looking statement. Forward-looking statements included in this repository are based on information available to GitHub as of the date they are made, and GitHub assumes no obligation to update any forward-looking statements. The forward-looking comments in the public feedback discussions do not represent a commitment, guarantee, obligation or promise to deliver any product or feature, or to deliver any product and feature by any particular date, and are intended to outline the general development plans. Customers should not rely on these public feedback discussions to make any purchasing decision. 65 | -------------------------------------------------------------------------------- /docs/Responsible-AI-for-Open-Source-Sweepstakes-Official-Rules.md: -------------------------------------------------------------------------------- 1 | # MICROSOFT RESPONSIBLE AI FOR OPEN SOURCE SWEEPSTAKES 2 | ## OFFICIAL RULES 3 | 4 | ### SPONSOR 5 | These Official Rules (“Rules”) govern the operation of the Microsoft Responsible AI for Open Source Sweepstakes (“Sweepstakes”). Microsoft Corporation, One Microsoft Way, Redmond, WA, 98052, USA, is the Sweepstakes sponsor (“Sponsor”). 6 | 7 | ### DEFINITIONS 8 | In these Rules, "Microsoft", "we", "our", and "us" refer to Sponsor and “you” and "yourself" refers to a Sweepstakes participant, or the parent/legal guardian of any Sweepstakes entrant who has not reached the age of majority to contractually obligate themselves in their legal place of residence. By entering you (your parent/legal guardian if you are not the age of majority in your legal place of residence) agree to be bound by these Rules. 9 | 10 | ### ENTRY PERIOD 11 | The Sweepstakes starts at 12:00 a.m. Pacific Time (PT) on July 24, 2025, and ends at 11:59 p.m. PT on August 21, 2025 (“Entry Period”). 12 | 13 | ### ELIGIBILITY 14 | To enter, you must be 18 years of age or older. If you are 18 years of age or older but have not reached the age of majority in your legal place of residence, then you must have consent of a parent/legal guardian. 15 | 16 | Employees and directors of Microsoft Corporation and its subsidiaries, affiliates, advertising agencies, and Sweepstakes Parties are not eligible, nor are persons involved in the execution or administration of this promotion, or the family members of each above (parents, children, siblings, spouse/domestic partners, or individuals residing in the same household). Void in Cuba, Iran, North Korea, Sudan, Syria, Region of Crimea, Russia, and where prohibited. 17 | 18 | ### HOW TO ENTER 19 | No Purchase Necessary. 20 | 21 | You will receive one Sweepstakes entry when you participate in the marked discussion on the GitHub Community during our entry period. There will be three (3) different challenges in total where you’ll be able to comment on the discussion stating that you completed the challenge. Challenges vary from sharing insights of codebase deep dive with AI, rewriting a Pull Request, and posting your learnings from an AI-generated code review. To participate in the GitHub Community, you must have a free GitHub account which you can sign up for at GitHub.com. 22 | 23 | The entry limit is one entry per challenge (there are three challenges). 24 | 25 | Any attempt by you to obtain more than the stated number of entries by using multiple/different accounts, identities, registrations, logins, or any other methods will void your entries and you may be disqualified. Use of any automated system to participate is prohibited. 26 | 27 | We are not responsible for excess, lost, late, or incomplete entries. If disputed, entries will be deemed submitted by the “authorized account holder” of the email address, social media account, or other method used to enter. The “authorized account holder” is the natural person assigned to an email address by an internet or online service provider, or other organization responsible for assigning email addresses. 28 | 29 | ### WINNER SELECTION AND NOTIFICATION 30 | Pending confirmation of eligibility, potential prize winners will be selected by Microsoft or their Agent in a random drawing from among all eligible entries received within 7 days following the Entry Period. 31 | 32 | Winners will be notified via the contact information provided during entry no more than 7 days following the drawing with prize claim instructions, including submission deadlines. If a selected winner cannot be contacted, is ineligible, fails to claim a prize or fails to return any forms, the selected winner will forfeit their prize and an alternate winner will be selected time allowing. If you are a potential winner and you are 18 or older but have not reached the age of majority in your legal place of residence, we may require your parent/legal guardian to sign all required forms on your behalf. Only three alternate winners will be selected, after which unclaimed prizes will remain unawarded. 33 | 34 | ### PRIZES 35 | The following prizes will be awarded: 36 | 37 | Ten (10) Grand Prizes. Each winner will receive: 38 | A(n) GitHub Shop voucher. Approximate Retail Value (ARV) $30.00. 39 | 40 | The ARV of electronic prizes is subject to price fluctuations in the consumer marketplace based on, among other things, any gap in time between the date the ARV is estimated for purposes of these Official Rules and the date the prize is awarded or redeemed. We will determine the value of the prize to be the fair market value at the time of prize award. 41 | 42 | The total Approximate Retail Value (ARV) of all prizes: $300 43 | 44 | We will only award one (1) prize per person/company during the Entry Period. No more than the stated number of prizes will be awarded. No substitution, transfer, or assignment of prize permitted, except that Microsoft reserves the right to substitute a prize of equal or greater value in the event the offered prize is unavailable. Microsoft products awarded as prizes are awarded “AS IS” and WITHOUT WARRANTY OF ANY KIND, express or implied (including any implied warranty of merchantability or fitness for a particular purpose); you assume the entire risk of quality and performance, and should the prizes prove defective, you assume the entire cost of all necessary servicing or repair. This is so even if the Microsoft product mentions a warranty on its packaging, in a manual, or in marketing materials; no warranty applies to Microsoft products awarded as prizes. 45 | 46 | Microsoft does not give any warranty of any kind, express or implied (including any implied warranty of merchantability or fitness for a particular purpose) on products made by a company other than Microsoft that are awarded as prizes. Please contact the manufacturer to see if it is covered by that company’s warranty. 47 | 48 | Prizes will be sent no later than 28 days after winner selection. Prize winners may be required to complete and return prize claim and/or tax forms (“Forms”) within the deadline stated in the winner notification. Taxes on the prize, if any, are the sole responsibility of the winner, who is advised to seek independent counsel regarding the tax implications of accepting a prize. By accepting a prize, you agree that Microsoft may use your entry, name, image and hometown online and in print, or in any other media, in connection with this Sweepstakes without payment or compensation to you, except where prohibited by law. 49 | 50 | ### ODDS 51 | The odds of winning are based on the number of eligible entries received. 52 | 53 | ### GENERAL CONDITIONS AND RELEASE OF LIABILITY 54 | To the extent allowed by law, by entering you agree to release and hold harmless Microsoft and its respective parents, partners, subsidiaries, affiliates, employees, and agents from any and all liability or any injury, loss, or damage of any kind arising in connection with this Sweepstakes or any prize won. 55 | 56 | All local laws apply. The decisions of Microsoft are final and binding. 57 | 58 | We reserve the right to cancel, change, or suspend this Sweepstakes for any reason, including cheating, technology failure, catastrophe, war, or any other unforeseen or unexpected event that affects the integrity of this Sweepstakes, whether human or mechanical. If the integrity of the Sweepstakes cannot be restored, we may select winners from among all eligible entries received before we had to cancel, change or suspend the Sweepstakes. 59 | 60 | If you attempt or we have strong reason to believe that you have compromised the integrity or the legitimate operation of this Sweepstakes by cheating, hacking, creating a bot or other automated program, or by committing fraud in any way, we may seek damages from you to the full extent of the law and you may be banned from participation in future Microsoft promotions. 61 | 62 | ### USE OF YOUR ENTRY 63 | Personal data you provide while entering this Sweepstakes will be used by Microsoft and/or its agents and prize fulfillers acting on Microsoft’s behalf only for the administration and operation of this Sweepstakes and in accordance with the Microsoft Privacy Statement. 64 | 65 | ### GOVERNING LAW 66 | This Sweepstakes will be governed by the laws of the State of Washington, and you consent to the exclusive jurisdiction and venue of the courts of the State of Washington for any disputes arising out of this Sweepstakes. 67 | 68 | ### WINNERS LIST 69 | Send an email to lgalante@microsoft.com with the subject line “Responsible AI for Open Source Sweepstakes winners” within 30 days of August 21, 2025 to receive a list of winners that received a prize worth $25.00 or more. 70 | -------------------------------------------------------------------------------- /docs/Fall2025-GitHub-Administration-Certification-Prep-Course-Sweepstakes.md: -------------------------------------------------------------------------------- 1 | **MICROSOFT FALL 2025 GITHUB ADMINISTRATION CERTIFICATION PREP COURSE SWEEPSTAKES** 2 | **OFFICIAL RULES** 3 | 4 | 1. **SPONSOR** 5 | 6 | These Official Rules (“Rules”) govern the operation of the Microsoft Fall 2025 GitHub Administration Certification Prep Course Sweepstakes (“Sweepstakes”). Microsoft Corporation, One Microsoft Way, Redmond, WA, 98052, USA, is the Sweepstakes sponsor (“Sponsor”). 7 | 8 | 2. **DEFINITIONS** 9 | 10 | In these Rules, "Microsoft", "we", "our", and "us" refer to Sponsor and “you” and "yourself" refers to a Sweepstakes participant, or the parent/legal guardian of any Sweepstakes entrant who has not reached the age of majority to contractually obligate themselves in their legal place of residence. By entering you (your parent/legal guardian if you are not the age of majority in your legal place of residence) agree to be bound by these Rules. 11 | 12 | 3. **ENTRY PERIOD** 13 | 14 | The Sweepstakes starts at 12:00 a.m. Pacific Time (“PT”) on September 29, 2025, and ends at 11:59 p.m. PT on November 1, 2025 (“Entry Period”): 15 | 16 | 17 | 4. **ELIGIBILITY** 18 | 19 | To enter, you must be fourteen (14) years of age or older with an active GitHub account. If you are fourteen (14) years of age or older but have not reached the age of majority in your legal place of residence, then you must have consent of a parent/legal guardian. 20 | 21 | Employees and directors of Microsoft Corporation and its subsidiaries, affiliates, advertising agencies, and Sweepstakes Parties are not eligible, nor are persons involved in the execution or administration of this promotion, or the family members of each above (parents, children, siblings, spouse/domestic partners, or individuals residing in the same household). Void in Cuba, Iran, North Korea, Sudan, Syria, Region of Crimea, Russia, and where otherwise prohibited by law. 22 | 23 | 5. **HOW TO ENTER** 24 | 25 | No Purchase Necessary. You will receive one (1) entry by visiting the web site for the Sweepstakes at [https://github.com/orgs/community/discussions/174475](https://github.com/orgs/community/discussions/174475) during the Entry Period and completing at least one (1) of the following tasks for one of the weekly marked discussions: 26 | 27 | 1. Complete a knowledge check quiz on the subject matter of the weekly discussion. All required questions must be answered to receive an entry. 28 | 2. Post a comment on the weekly discussion page sharing a publicly accessible resource. Your post and the resources you share must: 29 | 1. Be relevant to the subject matter of the weekly discussion; 30 | 2. NOT violate the privacy, intellectual property rights, or other rights of any other person or entity. You must have obtained any and all consents, approvals, or licenses required for you to submit your entry; and 31 | 3. NOT contain, as determined by us in our sole and absolute discretion, any content that is obscene or offensive, violent, defamatory, disparaging, or illegal, or that promotes alcohol, illegal drugs, tobacco, or a particular political agenda, or that communicates messages that may reflect negatively on the goodwill of Microsoft. 32 | 3. Post a comment on the weekly discussion page and ask a question. Your post and question must: 33 | 1. Be relevant to the subject matter of the weekly discussion; and 34 | 2. NOT contain, as determined by us in our sole and absolute discretion, any content that is obscene or offensive, violent, defamatory, disparaging, or illegal, or that promotes alcohol, illegal drugs, tobacco, or a particular political agenda, or that communicates messages that may reflect negatively on the goodwill of Microsoft. 35 | 36 | 37 | 38 | The entry limit is one (1) per person per weekly marked discussion, and a total of four (4) entries overall. Any attempt by you to obtain more than the stated number of entries by using multiple/different accounts, identities, registrations, logins, or any other methods will void your entries and you may be disqualified. Use of any automated system to participate is prohibited. 39 | 40 | 41 | 42 | We are not responsible for excess, lost, late, or incomplete entries. If disputed, entries will be deemed submitted by the “authorized account holder” of the email address, social media account, or other method used to enter. The “authorized account holder” is the natural person assigned to an email address by an internet or online service provider, or other organization responsible for assigning email addresses. 43 | 44 | 45 | 46 | 6. **WINNER SELECTION AND NOTIFICATION** 47 | 48 | Pending confirmation of eligibility, potential prize winners will be selected by Microsoft or their Agent within seven (7) days following the end of the Entry Period in a random drawing from among all eligible entries received. 49 | 50 | Winners will be notified via the contact information provided during entry no more than seven (7) days following the drawing with prize claim instructions, including submission deadlines. If a selected winner cannot be contacted, is ineligible, fails to claim a prize or fails to return any forms, the selected winner will forfeit their prize and an alternate winner will be selected time allowing. If you are a potential winner and you are fourteen (14) or older but have not reached the age of majority in your legal place of residence, we may require your parent/legal guardian to sign all required forms on your behalf. Only three (3) alternate winners will be selected, after which unclaimed prizes will remain unawarded. 51 | 52 | 7. **PRIZES** 53 | 54 | The following prizes will be awarded: 55 | 56 | **Fifteen (15) Grand Prizes.** Each winner will receive a GitHub Certification voucher. Approximate Retail Value (ARV) $50.00 USD. 57 | 58 | 59 | The total Approximate Retail Value (ARV) of all prizes: **$750.00 USD** 60 | 61 | We will only award one (1) prize per person overall. No more than the stated number of prizes will be awarded. No substitution, transfer, or assignment of prize permitted, except that Microsoft reserves the right to substitute a prize of equal or greater value in the event the offered prize is unavailable. Microsoft products awarded as prizes are awarded “AS IS” and WITHOUT WARRANTY OF ANY KIND, express or implied (including any implied warranty of merchantability or fitness for a particular purpose); you assume the entire risk of quality and performance, and should the prizes prove defective, you assume the entire cost of all necessary servicing or repair. This is so even if the Microsoft product mentions a warranty on its packaging, in a manual, or in marketing materials; no warranty applies to Microsoft products awarded as prizes. 62 | 63 | Microsoft does not give any warranty of any kind, express or implied (including any implied warranty of merchantability or fitness for a particular purpose) on products made by a company other than Microsoft that are awarded as prizes. Please contact the manufacturer to see if it is covered by that company’s warranty. 64 | 65 | Prizes will be sent no later than twenty-eight (28) days after winner selection. Prize winners may be required to complete and return prize claim and/or tax forms (“Forms”) within the deadline stated in the winner notification. Taxes on the prize, if any, are the sole responsibility of the winner, who is advised to seek independent counsel regarding the tax implications of accepting a prize. By accepting a prize, you agree that Microsoft may use your entry, name, image and hometown online and in print, or in any other media, in connection with this Sweepstakes without payment or compensation to you, except where prohibited by law. 66 | 67 | 8. **ODDS** 68 | 69 | 70 | The odds of winning are based on the number of eligible entries received. 71 | 72 | 9. **GENERAL CONDITIONS AND RELEASE OF LIABILITY** 73 | 74 | To the extent allowed by law, by entering you agree to release and hold harmless Microsoft and its respective parents, partners, subsidiaries, affiliates, employees, and agents from any and all liability or any injury, loss, or damage of any kind arising in connection with this Sweepstakes or any prize won. 75 | 76 | All local laws apply. The decisions of Microsoft are final and binding. We reserve the right to cancel, change, or suspend this Sweepstakes for any reason, including cheating, technology failure, catastrophe, war, or any other unforeseen or unexpected event that affects the integrity of this Sweepstakes, whether human or mechanical. If the integrity of the Sweepstakes cannot be restored, we may select winners from among all eligible entries received before we had to cancel, change or suspend the Sweepstakes. 77 | 78 | If you attempt or we have strong reason to believe that you have compromised the integrity or the legitimate operation of this Sweepstakes by cheating, hacking, creating a bot or other automated program, or by committing fraud in any way, we may seek damages from you to the full extent of the law and you may be banned from participation in future Microsoft promotions. 79 | 80 | 10. **USE OF YOUR ENTRY** 81 | 82 | Personal data you provide while entering this Sweepstakes will be used by Microsoft and/or its agents and prize fulfillers acting on Microsoft’s behalf only for the administration and operation of this Sweepstakes and in accordance with the [Microsoft Privacy Statement](https://go.microsoft.com/fwlink/?LinkId=521839). 83 | 84 | 11. **GOVERNING LAW** 85 | 86 | This Sweepstakes will be governed by the laws of the State of Washington, and you consent to the exclusive jurisdiction and venue of the courts of the State of Washington for any disputes arising out of this Sweepstakes. 87 | 88 | 12. **WINNERS LIST** 89 | 90 | Send an email to [lgalante@microsoft.com](mailto:lgalante@microsoft.com) with the subject line “Fall 2025 GitHub Administration Certification Prep Course Sweepstakes winners” within thirty (30) days of November 1, 2025 to receive a list of winners. 91 | -------------------------------------------------------------------------------- /.github/workflows/actions_labeller.yml: -------------------------------------------------------------------------------- 1 | name: Auto-Label Discussions for Actions Category 2 | 3 | on: 4 | discussion: 5 | types: [created] 6 | 7 | jobs: 8 | label-actions-discussion: 9 | if: ${{ contains(github.event.discussion.category.name, 'Actions') }} 10 | runs-on: ubuntu-latest 11 | env: 12 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 13 | steps: 14 | - name: Get discussion body html 15 | id: get_discussion_body_html 16 | env: 17 | OWNER: ${{ github.repository_owner }} 18 | REPO: ${{ github.event.repository.name }} 19 | DISCUSSION_NUMBER: ${{ github.event.discussion.number }} 20 | run: | 21 | gh api graphql -F owner=$OWNER -F name=$REPO -F number=$DISCUSSION_NUMBER -f query=' 22 | query($owner: String!, $name: String!, $number: Int!) { 23 | repository(owner: $owner, name: $name){ 24 | discussion(number: $number) { 25 | bodyHTML 26 | id 27 | } 28 | } 29 | }' > discussion_data.json 30 | 31 | echo 'DISCUSSION_BODY_HTML='$(jq -r '.data.repository.discussion.bodyHTML' discussion_data.json) >> $GITHUB_ENV 32 | echo 'DISCUSSION_ID='$(jq -r '.data.repository.discussion.id' discussion_data.json) >> $GITHUB_ENV 33 | 34 | - run: npm install jsdom dompurify 35 | 36 | - name: Extract Title and Body Text 37 | id: extract_text 38 | uses: actions/github-script@v6 39 | env: 40 | DISCUSSION_BODY_HTML: ${{ env.DISCUSSION_BODY_HTML }} 41 | DISCUSSION_TITLE: ${{ github.event.discussion.title }} 42 | with: 43 | result-encoding: string 44 | script: | 45 | const jsdom = require('jsdom'); 46 | const { JSDOM } = jsdom; 47 | const { DISCUSSION_BODY_HTML } = process.env; 48 | const fragment = JSDOM.fragment(DISCUSSION_BODY_HTML); 49 | let body = ''; 50 | const h3s = Array.from(fragment.querySelectorAll('h3')); 51 | h3s.forEach(h3 => { 52 | const heading = h3.textContent.trim(); 53 | let p = h3.nextElementSibling; 54 | while (p && p.tagName !== 'P') p = p.nextElementSibling; 55 | if (!p) return; 56 | if (heading === 'Discussion Details') { 57 | body = p.textContent.trim(); 58 | } 59 | }); 60 | body = body.replace(/^['\"]+|['\"]+$/g, ''); 61 | const title = process.env.DISCUSSION_TITLE || ''; 62 | core.info(`Extracted title: ${title}`); 63 | core.info(`Extracted body: ${body}`); 64 | return JSON.stringify({ title, body }); 65 | 66 | - name: Extract Primary and Secondary Topic Areas 67 | id: extract_topics 68 | uses: actions/github-script@v6 69 | env: 70 | DISCUSSION_BODY_HTML: ${{ env.DISCUSSION_BODY_HTML }} 71 | with: 72 | result-encoding: string 73 | script: | 74 | const jsdom = require('jsdom'); 75 | const { JSDOM } = jsdom; 76 | const { DISCUSSION_BODY_HTML } = process.env; 77 | const fragment = JSDOM.fragment(DISCUSSION_BODY_HTML); 78 | let primary = ''; 79 | let secondary = ''; 80 | const h3s = Array.from(fragment.querySelectorAll('h3')); 81 | h3s.forEach(h3 => { 82 | const heading = h3.textContent.trim(); 83 | let p = h3.nextElementSibling; 84 | while (p && p.tagName !== 'P') p = p.nextElementSibling; 85 | if (!p) return; 86 | if (heading === 'Why are you starting this discussion?') { 87 | primary = p.textContent.trim(); 88 | } 89 | if (heading === 'What GitHub Actions topic or product is this about?') { 90 | secondary = p.textContent.trim(); 91 | } 92 | }); 93 | core.info(`Extracted primary topic: ${primary}`); 94 | core.info(`Extracted secondary topic: ${secondary}`); 95 | return JSON.stringify({ primary, secondary }); 96 | 97 | - name: Auto-label by keyword search 98 | id: auto_label_keywords 99 | uses: actions/github-script@v6 100 | env: 101 | EXTRACT_TEXT_RESULT: ${{ steps.extract_text.outputs.result }} 102 | with: 103 | result-encoding: string 104 | script: | 105 | const jsdom = require('jsdom'); 106 | const { JSDOM } = jsdom; 107 | const createDOMPurify = require('dompurify'); 108 | const window = (new JSDOM('')).window; 109 | const DOMPurify = createDOMPurify(window); 110 | 111 | const labelMap = [ 112 | { 113 | label: 'Workflow Deployment', 114 | keywords: [ 115 | "deployment error", 116 | "publish artifact", 117 | "release failure", 118 | "deployment target", 119 | "github pages", 120 | "deployment issue", 121 | "release workflow", 122 | "target environment" 123 | ] 124 | }, 125 | { 126 | label: 'Workflow Configuration', 127 | keywords: [ 128 | "yaml syntax", 129 | "job dependency", 130 | "setup error", 131 | "workflow file", 132 | "configuration issue", 133 | "matrix strategy", 134 | "define env", 135 | "secret management", 136 | "environment setup", 137 | "config job" 138 | ] 139 | }, 140 | { 141 | label: 'Schedule & Cron Jobs', 142 | keywords: [ 143 | "cron job", 144 | "scheduled workflow", 145 | "timing issue", 146 | "delay trigger", 147 | "timezone error", 148 | "periodic run", 149 | "recurring schedule", 150 | "interval workflow", 151 | "scheduled trigger", 152 | "cron expression" 153 | ] 154 | }, 155 | { 156 | label: 'Metrics & Insights', 157 | keywords: [ 158 | "usage metrics", 159 | "performance trend", 160 | "analytics graph", 161 | "stats dashboard", 162 | "timeseries graph", 163 | "insight report", 164 | "metric tracking", 165 | "workflow analytics", 166 | "performance metric", 167 | "statistics report" 168 | ] 169 | } 170 | ]; 171 | const miscLabel = 'General'; 172 | let title = ''; 173 | let body = ''; 174 | try { 175 | const parsed = JSON.parse(process.env.EXTRACT_TEXT_RESULT); 176 | title = DOMPurify.sanitize(parsed.title || '', { ALLOWED_TAGS: [], ALLOWED_ATTR: [] }).trim(); 177 | body = DOMPurify.sanitize(parsed.body || '', { ALLOWED_TAGS: [], ALLOWED_ATTR: [] }).trim(); 178 | } catch (e) { 179 | core.error('Failed to parse or sanitize discussion text: ' + e.message); 180 | } 181 | const text = (title + ' ' + body).toLowerCase(); 182 | let foundLabel = miscLabel; 183 | core.info(`Auto-label debug: text to match: '${text}'`); 184 | for (const map of labelMap) { 185 | core.info(`Auto-label debug: checking label '${map.label}' with keywords: ${map.keywords.join(', ')}`); 186 | for (const k of map.keywords) { 187 | if (text.includes(k)) { 188 | core.info(`Auto-label debug: matched keyword '${k}' for label '${map.label}'`); 189 | foundLabel = map.label; 190 | break; 191 | } 192 | } 193 | if (foundLabel !== miscLabel) break; 194 | } 195 | core.info(`Auto-label debug: selected label: '${foundLabel}'`); 196 | return foundLabel; 197 | 198 | - name: Fetch label ID for primary topic 199 | id: fetch_primary_label_id 200 | env: 201 | OWNER: ${{ github.repository_owner }} 202 | REPO: ${{ github.event.repository.name }} 203 | TOPIC: ${{ fromJson(steps.extract_topics.outputs.result).primary }} 204 | run: | 205 | echo "DEBUG: Fetching label for primary topic: $TOPIC" 206 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$TOPIC" -f query=' 207 | query($owner: String!, $name: String!, $topic: String) { 208 | repository(owner: $owner, name: $name) { 209 | labels(first: 1, query: $topic) { 210 | edges { 211 | node { 212 | id 213 | name 214 | } 215 | } 216 | } 217 | } 218 | } 219 | ' > primary_label_data.json 220 | 221 | PRIMARY_LABEL_ID=$(jq -r '.data.repository.labels.edges[0]?.node?.id // empty' primary_label_data.json) 222 | echo "PRIMARY_LABEL_ID=$PRIMARY_LABEL_ID" >> $GITHUB_ENV 223 | 224 | - name: Fetch label ID for secondary topic 225 | id: fetch_secondary_label_id 226 | env: 227 | OWNER: ${{ github.repository_owner }} 228 | REPO: ${{ github.event.repository.name }} 229 | TOPIC: ${{ fromJson(steps.extract_topics.outputs.result).secondary }} 230 | run: | 231 | echo "DEBUG: Fetching label for secondary topic: $TOPIC" 232 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$TOPIC" -f query=' 233 | query($owner: String!, $name: String!, $topic: String) { 234 | repository(owner: $owner, name: $name) { 235 | labels(first: 1, query: $topic) { 236 | edges { 237 | node { 238 | id 239 | name 240 | } 241 | } 242 | } 243 | } 244 | } 245 | ' > secondary_label_data.json 246 | 247 | SECONDARY_LABEL_ID=$(jq -r '.data.repository.labels.edges[0]?.node?.id // empty' secondary_label_data.json) 248 | echo "SECONDARY_LABEL_ID=$SECONDARY_LABEL_ID" >> $GITHUB_ENV 249 | 250 | - name: Fetch label ID for auto-label 251 | id: fetch_auto_label_id 252 | env: 253 | OWNER: ${{ github.repository_owner }} 254 | REPO: ${{ github.event.repository.name }} 255 | TOPIC: ${{ steps.auto_label_keywords.outputs.result }} 256 | run: | 257 | gh api graphql -F owner=$OWNER -F name=$REPO -F topic="$TOPIC" -f query=' 258 | query($owner: String!, $name: String!, $topic: String) { 259 | repository(owner: $owner, name: $name) { 260 | labels(first: 1, query: $topic) { 261 | edges { 262 | node { 263 | id 264 | name 265 | } 266 | } 267 | } 268 | } 269 | }' > auto_label_data.json 270 | 271 | AUTO_LABEL_ID=$(jq -r '.data.repository.labels.edges[0]?.node?.id // empty' auto_label_data.json) 272 | echo "AUTO_LABEL_ID=$AUTO_LABEL_ID" >> $GITHUB_ENV 273 | 274 | - name: Apply labels to discussion 275 | if: ${{ env.PRIMARY_LABEL_ID != '' || env.SECONDARY_LABEL_ID != '' || env.AUTO_LABEL_ID != '' }} 276 | run: | 277 | echo "DEBUG: PRIMARY_LABEL_ID=$PRIMARY_LABEL_ID" 278 | echo "DEBUG: SECONDARY_LABEL_ID=$SECONDARY_LABEL_ID" 279 | echo "DEBUG: AUTO_LABEL_ID=$AUTO_LABEL_ID" 280 | LABEL_IDS=() 281 | if [ -n "$PRIMARY_LABEL_ID" ]; then 282 | LABEL_IDS+=("$PRIMARY_LABEL_ID") 283 | fi 284 | if [ -n "$SECONDARY_LABEL_ID" ]; then 285 | LABEL_IDS+=("$SECONDARY_LABEL_ID") 286 | fi 287 | if [ -n "$AUTO_LABEL_ID" ]; then 288 | LABEL_IDS+=("$AUTO_LABEL_ID") 289 | fi 290 | 291 | # Deduplicate LABEL_IDS 292 | LABEL_IDS=($(printf "%s\n" "${LABEL_IDS[@]}" | awk '!seen[$0]++')) 293 | echo "DEBUG: LABEL_IDS to apply: ${LABEL_IDS[@]}" 294 | 295 | # Apply labels 296 | gh api graphql -f query=' 297 | mutation($labelableId: ID!, $labelIds: [ID!]!) { 298 | addLabelsToLabelable(input: {labelableId: $labelableId, labelIds: $labelIds}) { 299 | labelable { 300 | labels(first: 10) { 301 | edges { 302 | node { 303 | id 304 | name 305 | } 306 | } 307 | } 308 | } 309 | } 310 | } 311 | ' -f labelableId=$DISCUSSION_ID $(printf -- "-f labelIds[]=%s " "${LABEL_IDS[@]}") 312 | -------------------------------------------------------------------------------- /.github/lib/discussions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "active_support" 4 | require "active_support/core_ext/date_and_time/calculations" 5 | require "active_support/core_ext/numeric/time" 6 | 7 | Discussion = Struct.new( 8 | :id, 9 | :url, 10 | :title, 11 | :labelled, 12 | :body, 13 | :created_at, 14 | :is_answered 15 | ) do 16 | def self.all(owner: nil, repo: nil) 17 | return [] if owner.nil? || repo.nil? 18 | 19 | cutoff_date = Time.now.advance(days: -60).to_date.to_s 20 | searchquery = "repo:#{owner}/#{repo} is:unanswered is:open is:unlocked updated:<#{cutoff_date} category:Copilot category:Accessibility category:\\\"Projects and Issues\\\" category:Sponsors category:Actions category:\\\"API and Webhooks\\\" category:\\\"Code Search and Navigation\\\" category:\\\"Code Security\\\" category:Codespaces category:Discussions category:Feed category:Lists category:Mobile category:npm category:Packages category:Pages category:Profile category:\\\"Pull Requests\\\" category:Repositories label:Question" 21 | 22 | query = <<~QUERY 23 | { 24 | search( 25 | first: 100 26 | after: "%ENDCURSOR%" 27 | query: "#{searchquery}" 28 | type: DISCUSSION 29 | ) { 30 | discussionCount 31 | ...Results 32 | pageInfo { 33 | hasNextPage 34 | endCursor 35 | } 36 | } 37 | rateLimit { 38 | limit 39 | cost 40 | remaining 41 | resetAt 42 | } 43 | } 44 | fragment Results on SearchResultItemConnection { 45 | nodes { 46 | ... on Discussion { 47 | id 48 | url 49 | title 50 | labels(first: 10) { 51 | nodes { 52 | name 53 | } 54 | } 55 | } 56 | } 57 | } 58 | QUERY 59 | 60 | GitHub.new.post(graphql: query) 61 | .map! { |r| r.dig('nodes') } 62 | .flatten 63 | .map do |c| 64 | labelled = c.dig("labels", "nodes").map { |l| l["name"] }.include?("inactive") 65 | Discussion.new( 66 | c["id"], 67 | c["url"], 68 | c["title"], 69 | labelled 70 | ) 71 | end 72 | end 73 | 74 | def self.to_be_closed(owner: nil, repo: nil) 75 | return [] if owner.nil? || repo.nil? 76 | 77 | cutoff_date = Time.now.advance(days: -30).to_date.to_s 78 | searchquery = "repo:#{owner}/#{repo} is:unanswered is:open is:unlocked updated:<#{cutoff_date} category:Copilot category:Accessibility category:\\\"Projects and Issues\\\" category:Sponsors category:Actions category:\\\"API and Webhooks\\\" category:\\\"Code Search and Navigation\\\" category:\\\"Code Security\\\" category:Codespaces category:Discussions category:Feed category:Lists category:Mobile category:npm category:Packages category:Pages category:Profile category:\\\"Pull Requests\\\" category:Repositories label:Question label:inactive" 79 | 80 | query = <<~QUERY 81 | { 82 | search( 83 | first: 100 84 | after: "%ENDCURSOR%" 85 | query: "#{searchquery}" 86 | type: DISCUSSION 87 | ) { 88 | discussionCount 89 | ...Results 90 | pageInfo { 91 | hasNextPage 92 | endCursor 93 | } 94 | } 95 | rateLimit { 96 | limit 97 | cost 98 | remaining 99 | resetAt 100 | } 101 | } 102 | fragment Results on SearchResultItemConnection { 103 | nodes { 104 | ... on Discussion { 105 | id 106 | url 107 | title 108 | comments(last:1) { 109 | nodes { 110 | author { 111 | login 112 | } 113 | } 114 | } 115 | labels(first: 10) { 116 | nodes { 117 | name 118 | } 119 | } 120 | } 121 | } 122 | } 123 | QUERY 124 | 125 | GitHub.new.post(graphql: query) 126 | .map! { |r| r.dig('nodes') } 127 | .flatten 128 | .select { |c| c.dig("comments", "nodes", 0, "author", "login") == "github-actions" } 129 | .map do |c| 130 | Discussion.new( 131 | c["id"], 132 | c["url"], 133 | c["title"], 134 | ) 135 | end 136 | end 137 | 138 | def self.to_remove_label(owner: nil, repo: nil) 139 | return [] if owner.nil? || repo.nil? 140 | 141 | searchquery = "repo:#{owner}/#{repo} is:unanswered is:open category:Copilot category:Accessibility category:\\\"Projects and Issues\\\" category:Sponsors category:Actions category:\\\"API and Webhooks\\\" category:\\\"Code Search and Navigation\\\" category:\\\"Code Security\\\" category:Codespaces category:Discussions category:Feed category:Lists category:Mobile category:npm category:Packages category:Pages category:Profile category:\\\"Pull Requests\\\" category:Repositories label:Question label:inactive" 142 | 143 | query = <<~QUERY 144 | { 145 | search( 146 | first: 100 147 | after: "%ENDCURSOR%" 148 | query: "#{searchquery}" 149 | type: DISCUSSION 150 | ) { 151 | discussionCount 152 | ...Results 153 | pageInfo { 154 | hasNextPage 155 | endCursor 156 | } 157 | } 158 | rateLimit { 159 | limit 160 | cost 161 | remaining 162 | resetAt 163 | } 164 | } 165 | fragment Results on SearchResultItemConnection { 166 | nodes { 167 | ... on Discussion { 168 | id 169 | url 170 | title 171 | comments(last:1) { 172 | nodes { 173 | author { 174 | login 175 | } 176 | } 177 | } 178 | labels(first: 10) { 179 | nodes { 180 | name 181 | } 182 | } 183 | } 184 | } 185 | } 186 | QUERY 187 | 188 | GitHub.new.post(graphql: query) 189 | .map! { |r| r.dig('nodes') } 190 | .flatten 191 | .reject { |c| c.dig("comments", "nodes", 0, "author", "login") == "github-actions" } 192 | .map do |c| 193 | Discussion.new( 194 | c["id"], 195 | c["url"], 196 | c["title"], 197 | ) 198 | end 199 | end 200 | 201 | def add_comment(body: nil) 202 | query = <<~QUERY 203 | mutation { 204 | addDiscussionComment( 205 | input: { 206 | body: """#{body}""", 207 | discussionId: "#{self.id}", 208 | clientMutationId: "rubyGraphQL" 209 | } 210 | ) { 211 | clientMutationId 212 | comment { 213 | id 214 | body 215 | } 216 | } 217 | } 218 | QUERY 219 | 220 | GitHub.new.mutate(graphql: query) 221 | end 222 | 223 | def add_label(label_id: nil) 224 | return if label_id.nil? 225 | 226 | query = <<~QUERY 227 | mutation { 228 | addLabelsToLabelable( 229 | input: { 230 | labelIds: ["#{label_id}"], 231 | labelableId: "#{self.id}", 232 | clientMutationId: "rubyGraphQL" 233 | } 234 | ) { 235 | clientMutationId 236 | } 237 | } 238 | QUERY 239 | 240 | GitHub.new.mutate(graphql: query) 241 | end 242 | 243 | def self.remove_label(node_id: nil, label_id: nil) 244 | return if node_id.nil? 245 | return if label_id.nil? 246 | 247 | query = <<~QUERY 248 | mutation { 249 | removeLabelsFromLabelable( 250 | input: { 251 | labelIds: ["#{label_id}"], 252 | labelableId: "#{node_id}", 253 | clientMutationId: "rubyGraphQL" 254 | } 255 | ) { 256 | clientMutationId 257 | } 258 | } 259 | QUERY 260 | 261 | GitHub.new.mutate(graphql: query) 262 | end 263 | 264 | def close_as_outdated 265 | query = <<~QUERY 266 | mutation { 267 | closeDiscussion( 268 | input: { 269 | discussionId: "#{self.id}", 270 | reason: OUTDATED, 271 | clientMutationId: "rubyGraphQL" 272 | } 273 | ) { 274 | clientMutationId 275 | } 276 | } 277 | QUERY 278 | 279 | GitHub.new.mutate(graphql: query) 280 | end 281 | 282 | def self.should_comment?(discussion_number: nil, owner: nil, repo: nil) 283 | return false if owner.nil? || repo.nil? 284 | return false if discussion_number.nil? 285 | 286 | query = <<~QUERY 287 | { 288 | repository(owner: "#{owner}", name: "#{repo}") { 289 | discussion(number: #{discussion_number}) { 290 | labels(first:100) { 291 | nodes { 292 | name 293 | } 294 | } 295 | comments(first:100) { 296 | nodes { 297 | author { 298 | login 299 | } 300 | } 301 | } 302 | } 303 | } 304 | } 305 | QUERY 306 | 307 | response = GitHub.new.post(graphql: query) 308 | .map { |r| 309 | { 310 | labels: r.dig("discussion", "labels", "nodes").map { |l| l["name"] }, 311 | comments_by: r.dig("discussion", "comments", "nodes").map { |c| c.dig("author", "login") } 312 | } 313 | }.first 314 | 315 | p response 316 | return false unless response[:labels].include?("Product Feedback") || response[:labels].include?("Bug") 317 | 318 | return false if response[:comments_by].include?("github-actions") 319 | 320 | true 321 | end 322 | 323 | def self.create_incident_discussion(repo_id:, title:, body:, category_id:, labels:) 324 | # create a new discussion in the specified category, applies the incident label, and returns the discussion id 325 | return if repo_id.nil? || title.nil? || body.nil? || category_id.nil? 326 | 327 | query = <<~QUERY 328 | mutation { 329 | createDiscussion( 330 | input: { 331 | categoryId: "#{category_id}", 332 | repositoryId: "#{repo_id}", 333 | clientMutationId: "rubyGraphQL", 334 | title: "#{title}", 335 | body: "#{body}" 336 | } 337 | ) { 338 | clientMutationId 339 | discussion { 340 | id 341 | body 342 | } 343 | } 344 | } 345 | QUERY 346 | 347 | incident_discussion_id = GitHub.new.mutate(graphql: query).dig("data", "createDiscussion", "discussion", "id") 348 | 349 | if labels 350 | addLabel = <<~QUERY 351 | mutation { 352 | addLabelsToLabelable( 353 | input: { 354 | labelIds: #{labels}, 355 | labelableId: "#{incident_discussion_id}", 356 | clientMutationId: "rubyGraphQL" 357 | } 358 | ) { 359 | clientMutationId 360 | 361 | } 362 | } 363 | QUERY 364 | 365 | GitHub.new.mutate(graphql: addLabel) 366 | end 367 | end 368 | 369 | def self.mark_comment_as_answer(comment_id:) 370 | # marks the given comment as the answer 371 | return if comment_id.nil? 372 | 373 | query = <<~QUERY 374 | mutation { 375 | markDiscussionCommentAsAnswer( 376 | input: { 377 | id: "#{comment_id}", 378 | clientMutationId: "rubyGraphQL" 379 | } 380 | ) { 381 | clientMutationId 382 | discussion { 383 | id 384 | answer { 385 | id 386 | } 387 | } 388 | } 389 | } 390 | QUERY 391 | 392 | GitHub.new.mutate(graphql: query) 393 | end 394 | 395 | def update_discussion(body:) 396 | return if body.nil? 397 | 398 | query = <<~QUERY 399 | mutation { 400 | updateDiscussion( 401 | input: { 402 | discussionId: "#{self.id}", 403 | body: "#{body}", 404 | clientMutationId: "rubyGraphQL" 405 | } 406 | ) { 407 | clientMutationId 408 | discussion { 409 | id 410 | } 411 | } 412 | } 413 | QUERY 414 | 415 | GitHub.new.mutate(graphql: query) 416 | end 417 | 418 | def find_most_recent_incident_comment_id(actor_login:) 419 | # finds the most recent comment generated by an incident action 420 | return nil if actor_login.nil? 421 | 422 | query = <<~QUERY 423 | query { 424 | node(id: "#{self.id}") { 425 | ... on Discussion { 426 | id 427 | comments(last: 10) { 428 | nodes{ 429 | id 430 | createdAt 431 | author { 432 | login 433 | } 434 | } 435 | } 436 | } 437 | } 438 | } 439 | QUERY 440 | 441 | # with the results, get an array of comments from the given actor login sorted by most recent 442 | comments = GitHub.new.post(graphql: query).first.dig("comments", "nodes") 443 | 444 | return nil if comments.empty? 445 | 446 | filtered_comments = comments.keep_if { |comment| comment["author"] && comment["author"]["login"] == actor_login } 447 | &.sort_by { |comment| comment["createdAt"] } 448 | .reverse 449 | 450 | # return the most recent comment's ID 451 | return nil if filtered_comments.empty? 452 | filtered_comments.first["id"] 453 | end 454 | 455 | def self.find_open_incident_discussions(owner:, repo:) 456 | return [] if owner.nil? || repo.nil? 457 | 458 | searchquery = "repo:#{owner}/#{repo} is:open author:github-actions[bot] label:\\\"Incident \:exclamation\:\\\"" 459 | 460 | query = <<~QUERY 461 | { 462 | search( 463 | first: 100 464 | query: "#{searchquery}" 465 | type: DISCUSSION 466 | ) { 467 | discussionCount 468 | ...Results 469 | } 470 | rateLimit { 471 | limit 472 | cost 473 | remaining 474 | resetAt 475 | } 476 | } 477 | fragment Results on SearchResultItemConnection { 478 | nodes { 479 | ... on Discussion { 480 | id 481 | url 482 | title 483 | body 484 | createdAt 485 | isAnswered 486 | } 487 | } 488 | } 489 | QUERY 490 | 491 | GitHub.new.post(graphql: query) 492 | .map! { |r| r.dig('nodes') } 493 | .flatten 494 | .map do |d| 495 | Discussion.new( 496 | d["id"], 497 | d["url"], 498 | d["title"], 499 | false, # :labelled 500 | d["body"], 501 | d["createdAt"], 502 | d["isAnswered"] 503 | ) 504 | end 505 | end 506 | 507 | def close_as_resolved 508 | # closes the post as resolved 509 | 510 | query = <<~QUERY 511 | mutation { 512 | closeDiscussion( 513 | input: { 514 | discussionId: "#{self.id}", 515 | reason: RESOLVED, 516 | clientMutationId: "rubyGraphQL" 517 | } 518 | ) { 519 | clientMutationId 520 | discussion { 521 | id 522 | } 523 | } 524 | } 525 | QUERY 526 | 527 | GitHub.new.mutate(graphql: query) 528 | end 529 | end 530 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Overview and Purpose 2 | 3 | Millions of developers across the world host millions of projects—both open and closed source—on GitHub. We're fortunate to be able to play a part in enabling collaboration across the developer community every day, which is a responsibility we don’t take lightly. Together, we all have the exciting opportunity to make this a community we can be proud of. 4 | 5 | GitHub Community, powered by GitHub Discussions, is intended to be a place for further collaboration, support, and brainstorming. This is a civilized place for connecting with other users, learning new skills, sharing feedback and ideas, and finding all the support you need for your GitHub projects. By participating in GitHub Community, you are agreeing to the same [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service) and [GitHub Acceptable Use Policies](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies) that apply to GitHub.com, as well as this GitHub Community-specific Code of Conduct. 6 | 7 | With this Code of Conduct, we hope to help you understand how best to collaborate in GitHub Community, what you can expect from moderators, and what type of actions or content may result in temporary or permanent suspension from community participation. We will investigate any abuse reports and may moderate public content within GitHub Community that we determine to be in violation of either the GitHub Terms of Service or this Code of Conduct. 8 | 9 | Our diverse user base brings different perspectives, ideas, and experiences, and ranges from people who created their first "Hello World" project last week to the most well-known software developers in the world. We are committed to making GitHub an environment that welcomes all the different voices and perspectives our community has to offer, while maintaining a safe place for developers to do their best work. 10 | 11 | ## Pledge 12 | 13 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in GitHub Community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 14 | 15 | ## Standards 16 | 17 | Treat GitHub Community with respect. We are a shared resource — a place to share skills, knowledge, and interests through ongoing conversation. 18 | 19 | The following are not hard and fast rules, merely aids to the human judgment of our community. Use these guidelines to keep this a clean, well-lighted place for civilized public discourse. 20 | 21 | ### _Best Practices for Maintaining a Strong Community_ 22 | 23 | The primary purpose of the GitHub community is to collaborate on software projects. We are committed to maintaining a community where users are free to express themselves and challenge one another's ideas, both technical and otherwise. At the same time, it's important that users remain respectful and allow space for others to contribute openly. In order to foster both a safe and productive environment, we encourage our community members to look to these guidelines to inform how they interact on our platform. Below, you’ll find some suggestions for how to have successful interactions as a valued member of the GitHub community. 24 | 25 | - Engage with consideration and respect. 26 | 27 | - **Be welcoming and open-minded** - New users join our community each day. Some are well-established developers, while others are just beginning. Be open to other ideas and experience levels. Make room for opinions other than your own and be welcoming to new collaborators and those just getting started. 28 | 29 | - **Be respectful** - Working in a collaborative environment means disagreements may happen. But remember to criticize ideas, not people. Share thoughtful, constructive criticism and be courteous to those you interact with. If you’re unable to engage respectfully, consider taking a step back or using some of our moderation tools to deescalate a tense situation. 30 | 31 | - **Be empathetic** - GitHub is a global community with people from a wide variety of backgrounds and perspectives, many of which may not be your own. Try to put yourself in others’ shoes and understand their feelings before you address them. Do your best to help make GitHub a community where others feel safe to make contributions, participate in discussions, and share different ideas. 32 | 33 | - Contribute in a positive and constructive way. 34 | - **Improve the discussion.** Help us make this a great place for discussion by always working to improve the discussion in some way, however small. If you are not sure your post adds to the conversation, think over what you want to say and try again later. 35 | 36 | The topics discussed here matter to us, and we want you to act as if they matter to you, too. Be respectful of the topics and the people discussing them, even if you disagree with some of what is being said. 37 | - **Be clear and stay on topic.** GitHub Community is for collaboration, sharing ideas, and helping each other get stuff done. Off-topic comments are a distraction (sometimes welcome, but usually not) from getting work done and being productive. Staying on topic helps produce positive and productive discussions. 38 | 39 | This applies to sharing links, as well. Any links shared in GitHub Community discussions should be shared with the intent of providing relevant and appropriate information. Links should not be posted to simply drive traffic or attention to a site. Links should always be accompanied by a full explanation of the content and purpose of the link. Posting links, especially unsolicited ones, without relevant and valuable context can come across as advertising or serving even more malicious purposes. 40 | 41 | - **Share mindfully.** When asking others to give you feedback or collaborate on a project, only share valuable and relevant resources to provide context. Don't post links that don't add value to the discussion, and don't post unsolicited links to your own projects or sites on other user's threads. 42 | 43 | Additionally, don't share sensitive information. This includes your own email address. We don't allow the sharing of such information in GitHub Community, as it can create security and privacy risks for the poster, as well as other users. If you'd like to invite other GitHub users to collaborate on a project or work with you, share a link to the repository in which the project you are working on exists. By sharing the link to your project repo - with some information on what your project is and what kind of help or feedback you're looking for - you can invite others to collaborate with you via issues or pull requests without having to share your private information. You can also add others as outside collaborators on your project repo to give them special permissions to help you develop your project. 44 | - **Keep it tidy.** Make the effort to put things in the right place, so that we can spend more time discussing and less time cleaning up. So: 45 | - Don’t start a discussion in the wrong category. 46 | - Don’t cross-post the same thing in multiple discussions. 47 | - Don’t post no-content replies. 48 | - Don't "bump" posts, unless you have new and relevant information to share. 49 | - Don’t divert a discussion by changing it midstream. 50 | 51 | Rather than posting “+1” or “Agreed”, use the upvote button. Rather than taking an existing discussion in a radically different direction, open a new discussion. 52 | 53 | - Be trustworthy. 54 | - **Always be honest.** Don’t knowingly share incorrect information or intentionally mislead other GitHub Community participants. If you don’t know the answer to someone’s question but still want to help, you can try helping them research or find resources instead. GitHub staff will also be active in GitHub Community, so if you’re unsure of an answer, it’s likely a moderator will be able to help. 55 | 56 | ### _What is not Allowed_ 57 | 58 | GitHub's [Acceptable Use Policies](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies), which are part of GitHub's [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service), set a baseline for what is not allowed on GitHub. Since GitHub Community is on GitHub.com, these terms and restrictions apply to GitHub Community, including the following restrictions: 59 | 60 | - **Anyone under the age of 13.** If you're a child under the age of 13, you may not have an account on GitHub. GitHub does not knowingly collect information from or direct any of our content specifically to children under 13. If we learn or have reason to suspect that you are a user who is under the age of 13, we will unfortunately have to close your GitHub.com account. We don't want to discourage you from learning to code, but those are the rules. Please see our [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service) for information about account termination. 61 | 62 | - **Creating new account after account restriction.** GitHub's [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service) state that "One person or legal entity may maintain no more than one free Account." Additional free accounts created to inquire about flagged or suspended accounts in GitHub will be removed. 63 | 64 | - **Other conduct which could reasonably be considered inappropriate in a professional setting.** GitHub Community is a professional space and should be treated as such. 65 | 66 | - **Violation of Terms of Service.** If your GitHub.com account is identified in violation of [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service) we will have to close your account. 67 | 68 | ### _Reasonable use of AI generated content_ 69 | 70 | We love experimenting with new technologies, and we are especially fond of [GitHub Copilot](https://github.com/features/copilot). But as with all new technology, many of us are still getting accustomed to using generative AI tools the most effectively. Here are important guidelines to follow when using generative AI to answer questions in the community: 71 | 72 | - Take personal responsibility for everything you post. 73 | - Read and revise the content before you post it; use your own authentic voice. 74 | - Use your expertise as a developer to verify that the answer works and makes sense. 75 | - Do not just post AI-generated content verbatim to inflate your reputation or give a false impression of product expertise. 76 | - AI tools will often answer in an authoritative tone that sounds like a tech support professional. Be careful not to [mislead other users](https://docs.github.com/en/site-policy/acceptable-use-policies/github-impersonation) into thinking that this authoritative tone means they are receiving an official response from GitHub. 77 | 78 | Additionally, all of the guidelines listed in the previous section ([Best Practices for Maintaining a Strong Community](https://docs.github.com/en/site-policy/github-terms/github-community-code-of-conduct#best-practices-for-maintaining-a-strong-community)) also apply here. 79 | 80 | The community is here for users to build trust through authentic reputations. Not adhering to these guidelines may, in some cases, constitute a Code of Conduct violation. Refer to [the enforcement section](#enforcement) below for more information. 81 | 82 | ## Enforcement 83 | 84 | ### _What GitHub Community Participants Can Do_ 85 | 86 | - **If you see a problem, report it.** Moderators have special authority; they are responsible for this GitHub Community. But so are you. With your help, moderators can be community facilitators, not just janitors or police. 87 | 88 | When you see bad behavior, don’t reply. It encourages the bad behavior by acknowledging it, consumes your energy, and wastes everyone’s time. You can report a disruptive user or disruptive content to GitHub. For more information, see "[AUTOTITLE](/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam)." 89 | 90 | ### Our Responsibilities 91 | 92 | There are a variety of actions that we may take in response to inappropriate behavior or content. It usually depends on the exact circumstances of a particular case. We recognize that sometimes people may say or do inappropriate things for any number of reasons. Perhaps they did not realize how their words would be perceived. Or maybe they just let their emotions get the best of them. Of course, sometimes, there are folks who just want to spam or cause trouble. 93 | 94 | Each case requires a different approach, and we try to tailor our response to meet the needs of the situation. We'll review each situation on a case-by-case basis. In each case, we will have a diverse team investigate the content and surrounding facts and respond as appropriate, using this Code of Conduct to guide our decision. 95 | 96 | Actions we may take in response to a flag or abuse report include, but are not limited to: 97 | - Content Removal 98 | - Content Blocking 99 | - GitHub Account Suspension 100 | - GitHub Account Termination 101 | 102 | GitHub Community moderators who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the GitHub Community's leadership. 103 | 104 | ## Contacting GitHub Staff 105 | 106 | If, for any reason, you want to contact GitHub Staff, the Community Managers, Administrators, or Moderators of GitHub Community privately, you can use our [Support contact form](https://support.github.com/contact?tags=docs-community-support). Contacting any member of GitHub Staff via unsolicited mentions or pings, or via channels other than GitHub Community itself, or the Support contact form is strongly discouraged and may be considered a violation of our prohibition against harassment. 107 | 108 | Let's work together to keep GitHub Community a place where people feel safe to participate by being respectful of them and their time. 109 | 110 | ## Legal Notices 111 | 112 | Yes, legalese is boring, but we must protect ourselves – and by extension, you and your data – against unfriendly folks. We have a [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service), which includes our [Acceptable Use Policies](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies), and our [Privacy Statement](https://docs.github.com/en/site-policy/privacy-policies/github-privacy-statement) describing your (and our) behavior and rights related to content, privacy, and laws. To use this service, you must agree to abide by our [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service), [GitHub Acceptable Use Policies](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies) and the [Privacy Statement](https://docs.github.com/en/site-policy/privacy-policies/github-privacy-statement). 113 | 114 | This Code of Conduct does not modify our [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service)—which includes our [Acceptable Use Policies](https://docs.github.com/en/site-policy/acceptable-use-policies/github-acceptable-use-policies)—and is not intended to be a complete list. GitHub retains full discretion under the [Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service) to remove or restrict any content or accounts for activity that violates those policies, including because it is unlawful, offensive, threatening, libelous, defamatory, pornographic, obscene or otherwise objectionable, or violates any party's intellectual property or our Terms of Service. This Code of Conduct describes when we will exercise that discretion. 115 | 116 | ### Data Retention and Deletion of Data 117 | 118 | If you're a GitHub user, you may access, update, alter, or delete your basic user profile information by [editing your user profile](https://github.com/settings/profile) or contacting [GitHub Support](https://support.github.com/contact). We will retain and use your information as necessary to comply with our legal obligations, resolve disputes, and enforce our agreements, but barring legal requirements, will delete your full profile (within reason) within 90 days of your request. For more information please see the [GitHub Privacy Statement](https://docs.github.com/en/site-policy/privacy-policies/github-privacy-statement). 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution 4.0 International Public License 58 | 59 | By exercising the Licensed Rights (defined below), You accept and agree 60 | to be bound by the terms and conditions of this Creative Commons 61 | Attribution 4.0 International Public License ("Public License"). To the 62 | extent this Public License may be interpreted as a contract, You are 63 | granted the Licensed Rights in consideration of Your acceptance of 64 | these terms and conditions, and the Licensor grants You such rights in 65 | consideration of benefits the Licensor receives from making the 66 | Licensed Material available under these terms and conditions. 67 | 68 | 69 | Section 1 -- Definitions. 70 | 71 | a. Adapted Material means material subject to Copyright and Similar 72 | Rights that is derived from or based upon the Licensed Material 73 | and in which the Licensed Material is translated, altered, 74 | arranged, transformed, or otherwise modified in a manner requiring 75 | permission under the Copyright and Similar Rights held by the 76 | Licensor. For purposes of this Public License, where the Licensed 77 | Material is a musical work, performance, or sound recording, 78 | Adapted Material is always produced where the Licensed Material is 79 | synched in timed relation with a moving image. 80 | 81 | b. Adapter's License means the license You apply to Your Copyright 82 | and Similar Rights in Your contributions to Adapted Material in 83 | accordance with the terms and conditions of this Public License. 84 | 85 | c. Copyright and Similar Rights means copyright and/or similar rights 86 | closely related to copyright including, without limitation, 87 | performance, broadcast, sound recording, and Sui Generis Database 88 | Rights, without regard to how the rights are labeled or 89 | categorized. For purposes of this Public License, the rights 90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 91 | Rights. 92 | 93 | d. Effective Technological Measures means those measures that, in the 94 | absence of proper authority, may not be circumvented under laws 95 | fulfilling obligations under Article 11 of the WIPO Copyright 96 | Treaty adopted on December 20, 1996, and/or similar international 97 | agreements. 98 | 99 | e. Exceptions and Limitations means fair use, fair dealing, and/or 100 | any other exception or limitation to Copyright and Similar Rights 101 | that applies to Your use of the Licensed Material. 102 | 103 | f. Licensed Material means the artistic or literary work, database, 104 | or other material to which the Licensor applied this Public 105 | License. 106 | 107 | g. Licensed Rights means the rights granted to You subject to the 108 | terms and conditions of this Public License, which are limited to 109 | all Copyright and Similar Rights that apply to Your use of the 110 | Licensed Material and that the Licensor has authority to license. 111 | 112 | h. Licensor means the individual(s) or entity(ies) granting rights 113 | under this Public License. 114 | 115 | i. Share means to provide material to the public by any means or 116 | process that requires permission under the Licensed Rights, such 117 | as reproduction, public display, public performance, distribution, 118 | dissemination, communication, or importation, and to make material 119 | available to the public including in ways that members of the 120 | public may access the material from a place and at a time 121 | individually chosen by them. 122 | 123 | j. Sui Generis Database Rights means rights other than copyright 124 | resulting from Directive 96/9/EC of the European Parliament and of 125 | the Council of 11 March 1996 on the legal protection of databases, 126 | as amended and/or succeeded, as well as other essentially 127 | equivalent rights anywhere in the world. 128 | 129 | k. You means the individual or entity exercising the Licensed Rights 130 | under this Public License. Your has a corresponding meaning. 131 | 132 | 133 | Section 2 -- Scope. 134 | 135 | a. License grant. 136 | 137 | 1. Subject to the terms and conditions of this Public License, 138 | the Licensor hereby grants You a worldwide, royalty-free, 139 | non-sublicensable, non-exclusive, irrevocable license to 140 | exercise the Licensed Rights in the Licensed Material to: 141 | 142 | a. reproduce and Share the Licensed Material, in whole or 143 | in part; and 144 | 145 | b. produce, reproduce, and Share Adapted Material. 146 | 147 | 2. Exceptions and Limitations. For the avoidance of doubt, where 148 | Exceptions and Limitations apply to Your use, this Public 149 | License does not apply, and You do not need to comply with 150 | its terms and conditions. 151 | 152 | 3. Term. The term of this Public License is specified in Section 153 | 6(a). 154 | 155 | 4. Media and formats; technical modifications allowed. The 156 | Licensor authorizes You to exercise the Licensed Rights in 157 | all media and formats whether now known or hereafter created, 158 | and to make technical modifications necessary to do so. The 159 | Licensor waives and/or agrees not to assert any right or 160 | authority to forbid You from making technical modifications 161 | necessary to exercise the Licensed Rights, including 162 | technical modifications necessary to circumvent Effective 163 | Technological Measures. For purposes of this Public License, 164 | simply making modifications authorized by this Section 2(a) 165 | (4) never produces Adapted Material. 166 | 167 | 5. Downstream recipients. 168 | 169 | a. Offer from the Licensor -- Licensed Material. Every 170 | recipient of the Licensed Material automatically 171 | receives an offer from the Licensor to exercise the 172 | Licensed Rights under the terms and conditions of this 173 | Public License. 174 | 175 | b. No downstream restrictions. You may not offer or impose 176 | any additional or different terms or conditions on, or 177 | apply any Effective Technological Measures to, the 178 | Licensed Material if doing so restricts exercise of the 179 | Licensed Rights by any recipient of the Licensed 180 | Material. 181 | 182 | 6. No endorsement. Nothing in this Public License constitutes or 183 | may be construed as permission to assert or imply that You 184 | are, or that Your use of the Licensed Material is, connected 185 | with, or sponsored, endorsed, or granted official status by, 186 | the Licensor or others designated to receive attribution as 187 | provided in Section 3(a)(1)(A)(i). 188 | 189 | b. Other rights. 190 | 191 | 1. Moral rights, such as the right of integrity, are not 192 | licensed under this Public License, nor are publicity, 193 | privacy, and/or other similar personality rights; however, to 194 | the extent possible, the Licensor waives and/or agrees not to 195 | assert any such rights held by the Licensor to the limited 196 | extent necessary to allow You to exercise the Licensed 197 | Rights, but not otherwise. 198 | 199 | 2. Patent and trademark rights are not licensed under this 200 | Public License. 201 | 202 | 3. To the extent possible, the Licensor waives any right to 203 | collect royalties from You for the exercise of the Licensed 204 | Rights, whether directly or through a collecting society 205 | under any voluntary or waivable statutory or compulsory 206 | licensing scheme. In all other cases the Licensor expressly 207 | reserves any right to collect such royalties. 208 | 209 | 210 | Section 3 -- License Conditions. 211 | 212 | Your exercise of the Licensed Rights is expressly made subject to the 213 | following conditions. 214 | 215 | a. Attribution. 216 | 217 | 1. If You Share the Licensed Material (including in modified 218 | form), You must: 219 | 220 | a. retain the following if it is supplied by the Licensor 221 | with the Licensed Material: 222 | 223 | i. identification of the creator(s) of the Licensed 224 | Material and any others designated to receive 225 | attribution, in any reasonable manner requested by 226 | the Licensor (including by pseudonym if 227 | designated); 228 | 229 | ii. a copyright notice; 230 | 231 | iii. a notice that refers to this Public License; 232 | 233 | iv. a notice that refers to the disclaimer of 234 | warranties; 235 | 236 | v. a URI or hyperlink to the Licensed Material to the 237 | extent reasonably practicable; 238 | 239 | b. indicate if You modified the Licensed Material and 240 | retain an indication of any previous modifications; and 241 | 242 | c. indicate the Licensed Material is licensed under this 243 | Public License, and include the text of, or the URI or 244 | hyperlink to, this Public License. 245 | 246 | 2. You may satisfy the conditions in Section 3(a)(1) in any 247 | reasonable manner based on the medium, means, and context in 248 | which You Share the Licensed Material. For example, it may be 249 | reasonable to satisfy the conditions by providing a URI or 250 | hyperlink to a resource that includes the required 251 | information. 252 | 253 | 3. If requested by the Licensor, You must remove any of the 254 | information required by Section 3(a)(1)(A) to the extent 255 | reasonably practicable. 256 | 257 | 4. If You Share Adapted Material You produce, the Adapter's 258 | License You apply must not prevent recipients of the Adapted 259 | Material from complying with this Public License. 260 | 261 | 262 | Section 4 -- Sui Generis Database Rights. 263 | 264 | Where the Licensed Rights include Sui Generis Database Rights that 265 | apply to Your use of the Licensed Material: 266 | 267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 268 | to extract, reuse, reproduce, and Share all or a substantial 269 | portion of the contents of the database; 270 | 271 | b. if You include all or a substantial portion of the database 272 | contents in a database in which You have Sui Generis Database 273 | Rights, then the database in which You have Sui Generis Database 274 | Rights (but not its individual contents) is Adapted Material; and 275 | 276 | c. You must comply with the conditions in Section 3(a) if You Share 277 | all or a substantial portion of the contents of the database. 278 | 279 | For the avoidance of doubt, this Section 4 supplements and does not 280 | replace Your obligations under this Public License where the Licensed 281 | Rights include other Copyright and Similar Rights. 282 | 283 | 284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 285 | 286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 296 | 297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 306 | 307 | c. The disclaimer of warranties and limitation of liability provided 308 | above shall be interpreted in a manner that, to the extent 309 | possible, most closely approximates an absolute disclaimer and 310 | waiver of all liability. 311 | 312 | 313 | Section 6 -- Term and Termination. 314 | 315 | a. This Public License applies for the term of the Copyright and 316 | Similar Rights licensed here. However, if You fail to comply with 317 | this Public License, then Your rights under this Public License 318 | terminate automatically. 319 | 320 | b. Where Your right to use the Licensed Material has terminated under 321 | Section 6(a), it reinstates: 322 | 323 | 1. automatically as of the date the violation is cured, provided 324 | it is cured within 30 days of Your discovery of the 325 | violation; or 326 | 327 | 2. upon express reinstatement by the Licensor. 328 | 329 | For the avoidance of doubt, this Section 6(b) does not affect any 330 | right the Licensor may have to seek remedies for Your violations 331 | of this Public License. 332 | 333 | c. For the avoidance of doubt, the Licensor may also offer the 334 | Licensed Material under separate terms or conditions or stop 335 | distributing the Licensed Material at any time; however, doing so 336 | will not terminate this Public License. 337 | 338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 339 | License. 340 | 341 | 342 | Section 7 -- Other Terms and Conditions. 343 | 344 | a. The Licensor shall not be bound by any additional or different 345 | terms or conditions communicated by You unless expressly agreed. 346 | 347 | b. Any arrangements, understandings, or agreements regarding the 348 | Licensed Material not stated herein are separate from and 349 | independent of the terms and conditions of this Public License. 350 | 351 | 352 | Section 8 -- Interpretation. 353 | 354 | a. For the avoidance of doubt, this Public License does not, and 355 | shall not be interpreted to, reduce, limit, restrict, or impose 356 | conditions on any use of the Licensed Material that could lawfully 357 | be made without permission under this Public License. 358 | 359 | b. To the extent possible, if any provision of this Public License is 360 | deemed unenforceable, it shall be automatically reformed to the 361 | minimum extent necessary to make it enforceable. If the provision 362 | cannot be reformed, it shall be severed from this Public License 363 | without affecting the enforceability of the remaining terms and 364 | conditions. 365 | 366 | c. No term or condition of this Public License will be waived and no 367 | failure to comply consented to unless expressly agreed to by the 368 | Licensor. 369 | 370 | d. Nothing in this Public License constitutes or may be interpreted 371 | as a limitation upon, or waiver of, any privileges and immunities 372 | that apply to the Licensor or You, including from the legal 373 | processes of any jurisdiction or authority. 374 | 375 | 376 | ======================================================================= 377 | 378 | Creative Commons is not a party to its public 379 | licenses. Notwithstanding, Creative Commons may elect to apply one of 380 | its public licenses to material it publishes and in those instances 381 | will be considered the “Licensor.” The text of the Creative Commons 382 | public licenses is dedicated to the public domain under the CC0 Public 383 | Domain Dedication. Except for the limited purpose of indicating that 384 | material is shared under a Creative Commons public license or as 385 | otherwise permitted by the Creative Commons policies published at 386 | creativecommons.org/policies, Creative Commons does not authorize the 387 | use of the trademark "Creative Commons" or any other trademark or logo 388 | of Creative Commons without its prior written consent including, 389 | without limitation, in connection with any unauthorized modifications 390 | to any of its public licenses or any other arrangements, 391 | understandings, or agreements concerning use of licensed material. For 392 | the avoidance of doubt, this paragraph does not form part of the 393 | public licenses. 394 | 395 | Creative Commons may be contacted at creativecommons.org. 396 | --------------------------------------------------------------------------------