diff --git a/.github/labeler.README.md b/.github/labeler.README.md deleted file mode 100644 index 502ebb98a8d0..000000000000 --- a/.github/labeler.README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Issue-Labeler Workflows - -This repository uses actions from [dotnet/issue-labeler](https://github.com/dotnet/issue-labeler) to predict area labels for issues and pull requests. - -The following workflow templates were imported and updated from [dotnet/issue-labeler/wiki/Onboarding](https://github.com/dotnet/issue-labeler/wiki/Onboarding): - -1. `labeler-cache-retention.yml` -2. `labeler-predict-issues.yml` -3. `labeler-predict-pulls.yml` -4. `labeler-promote.yml` -5. `labeler-train.yml` - -## Repository Configuration - -Across these workflows, the following changes were made to configure the issue labeler for this repository: - -1. Set `LABEL_PREFIX` to `"area-"`: - - `labeler-predict-issues.yml` - - `labeler-predict-pulls.yml` - - `labeler-train.yml` -2. Set `DEFAULT_LABEL` to `"needs-area-label"`: - - `labeler-predict-issues.yml` - - `labeler-predict-pulls.yml` -3. Remove the `EXCLUDED_AUTHORS` value as we do not bypass labeling for any authors' issues/pulls in this repository: - - `labeler-predict-issues.yml` - - `labeler-predict-pulls.yml` -4. Update the pull request labeling branches to include `main` and `release/*`: - - `labeler-predict-pulls.yml` -5. Remove the `repository` input for training the models against another repository: - - `labeler-train.yml` -6. Update the cache retention cron schedule to an arbitrary time of day: - - `labeler-cache-retention.yml` diff --git a/.github/workflows/labeler-cache-retention.yml b/.github/workflows/labeler-cache-retention.yml deleted file mode 100644 index 151ff1c9d09d..000000000000 --- a/.github/workflows/labeler-cache-retention.yml +++ /dev/null @@ -1,40 +0,0 @@ -# Workflow template imported and updated from: -# https://github.com/dotnet/issue-labeler/wiki/Onboarding -# -# See labeler.md for more information -# -# Regularly restore the prediction models from cache to prevent cache eviction -name: "Labeler: Cache Retention" - -# For more information about GitHub's action cache limits and eviction policy, see: -# https://docs.github.com/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy - -on: - schedule: - - cron: "32 16 * * *" # 16:32 every day (arbitrary time daily) - - workflow_dispatch: - inputs: - cache_key: - description: "The cache key suffix to use for restoring the model from cache. Defaults to 'ACTIVE'." - required: true - default: "ACTIVE" - -env: - CACHE_KEY: ${{ inputs.cache_key || 'ACTIVE' }} - -jobs: - restore-cache: - # Do not automatically run the workflow on forks outside the 'dotnet' org - if: ${{ github.event_name == 'workflow_dispatch' || github.repository_owner == 'dotnet' }} - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - type: ["issues", "pulls"] - steps: - - uses: dotnet/issue-labeler/restore@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: ${{ matrix.type }} - cache_key: ${{ env.CACHE_KEY }} - fail-on-cache-miss: true diff --git a/.github/workflows/labeler-predict-issues.yml b/.github/workflows/labeler-predict-issues.yml deleted file mode 100644 index a12efc1512af..000000000000 --- a/.github/workflows/labeler-predict-issues.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Workflow template imported and updated from: -# https://github.com/dotnet/issue-labeler/wiki/Onboarding -# -# See labeler.md for more information -# -# Predict labels for Issues using a trained model -name: "Labeler: Predict (Issues)" - -on: - # Only automatically predict area labels when issues are first opened - issues: - types: opened - - # Allow dispatching the workflow via the Actions UI, specifying ranges of numbers - workflow_dispatch: - inputs: - issues: - description: "Issue Numbers (comma-separated list of ranges)." - required: true - cache_key: - description: "The cache key suffix to use for restoring the model. Defaults to 'ACTIVE'." - required: true - default: "ACTIVE" - -env: - # Do not allow failure for jobs triggered automatically (as this causes red noise on the workflows list) - ALLOW_FAILURE: ${{ github.event_name == 'workflow_dispatch' }} - - LABEL_PREFIX: "area-" - THRESHOLD: 0.40 - DEFAULT_LABEL: "needs-area-label" - -jobs: - predict-issue-label: - # Do not automatically run the workflow on forks outside the 'dotnet' org - if: ${{ github.event_name == 'workflow_dispatch' || github.repository_owner == 'dotnet' }} - runs-on: ubuntu-latest - permissions: - issues: write - steps: - - name: "Restore issues model from cache" - id: restore-model - uses: dotnet/issue-labeler/restore@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: issues - fail-on-cache-miss: ${{ env.ALLOW_FAILURE }} - quiet: true - - - name: "Predict issue labels" - id: prediction - if: ${{ steps.restore-model.outputs.cache-hit == 'true' }} - uses: dotnet/issue-labeler/predict@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - issues: ${{ inputs.issues || github.event.issue.number }} - label_prefix: ${{ env.LABEL_PREFIX }} - threshold: ${{ env.THRESHOLD }} - default_label: ${{ env.DEFAULT_LABEL }} - env: - GITHUB_TOKEN: ${{ github.token }} - continue-on-error: ${{ !env.ALLOW_FAILURE }} diff --git a/.github/workflows/labeler-predict-pulls.yml b/.github/workflows/labeler-predict-pulls.yml deleted file mode 100644 index 6a75b390be09..000000000000 --- a/.github/workflows/labeler-predict-pulls.yml +++ /dev/null @@ -1,133 +0,0 @@ -# Workflow template imported and updated from: -# https://github.com/dotnet/issue-labeler/wiki/Onboarding -# -# See labeler.md for more information -# -# Predict labels for Pull Requests using a trained model -name: "Labeler: Predict (Pulls)" - -on: - # Per to the following documentation: - # https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target - # - # The `pull_request_target` event runs in the context of the base of the pull request, rather - # than in the context of the merge commit, as the `pull_request` event does. This prevents - # execution of unsafe code from the head of the pull request that could alter the repository - # or steal any secrets you use in your workflow. This event allows your workflow to do things - # like label or comment on pull requests from forks. - # - # Only automatically predict area labels when pull requests are first opened - pull_request_target: - types: opened - - # Configure the branches that need to have PRs labeled - branches: - - main - - # Poll for open pull requests that need labels every 5 minutes - schedule: - - cron: "*/5 * * * *" - - # Allow dispatching the workflow via the Actions UI, specifying ranges of numbers - # If no pull request numbers are provided, it behaves as a polling event - workflow_dispatch: - inputs: - pulls: - description: "Pull Request Numbers (comma-separated list of ranges). Leave empty to poll." - required: false - cache_key: - description: "The cache key suffix to use for restoring the model. Defaults to 'ACTIVE'." - required: true - default: "ACTIVE" - -env: - # Do not allow failure for jobs triggered automatically (this can block PR merge) - ALLOW_FAILURE: ${{ github.event_name == 'workflow_dispatch' }} - - LABEL_PREFIX: "area-" - THRESHOLD: 0.40 - DEFAULT_LABEL: "needs-area-label" - -jobs: - poll-pull-requests: - # Run on schedule trigger or workflow_dispatch without PR numbers, within the 'dotnet' org - if: ${{ (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.pulls == '')) && github.repository_owner == 'dotnet' }} - runs-on: ubuntu-latest - permissions: - actions: read - pull-requests: read - outputs: - pulls: ${{ steps.get-pulls.outputs.pulls }} - steps: - - name: "Get open pull requests needing labels" - id: get-pulls - env: - GITHUB_TOKEN: ${{ github.token }} - run: | - # Get the last successful schedule run's timestamp (minus 5 minutes for overlap) - last_run=$(gh run list --repo ${{ github.repository }} --workflow "${{ github.workflow }}" --event schedule --status success --limit 1 --json updatedAt --jq '.[0].updatedAt // empty') - - if [ -n "$last_run" ]; then - # Subtract 5 minutes from the last run timestamp for overlap - since=$(date -u -d "$last_run - 5 minutes" +"%Y-%m-%dT%H:%M:%SZ") - echo "Filtering PRs updated since: $since (last run: $last_run)" - pulls=$(gh pr list --repo ${{ github.repository }} --state open --json number,labels,updatedAt --limit 1000 --search "updated:>=$since") - else - # No previous run found; get all open pull requests - echo "No previous schedule run found. Getting all open pull requests." - pulls=$(gh pr list --repo ${{ github.repository }} --state open --json number,labels --limit 1000) - fi - - # Filter to PRs that don't have a label starting with LABEL_PREFIX - needs_label=$(echo "$pulls" | jq -r --arg prefix "${{ env.LABEL_PREFIX }}" ' - [.[] | select( - (.labels | map(.name) | any(startswith($prefix)) | not) - ) | .number] | join(",") - ') - - echo "Pull requests needing labels: $needs_label" - echo "pulls=$needs_label" >> $GITHUB_OUTPUT - - predict-pull-label: - # The 'if' uses always() so this job runs even when poll-pull-requests is skipped - # Do not automatically run the workflow on forks outside the 'dotnet' org - if: ${{ always() && (github.event_name == 'workflow_dispatch' || github.repository_owner == 'dotnet') }} - needs: [poll-pull-requests] - runs-on: ubuntu-latest - permissions: - pull-requests: write - steps: - - name: "Determine pull requests to process" - id: determine-pulls - run: | - if [ "${{ github.event_name }}" == "workflow_dispatch" ] && [ -n "${{ inputs.pulls }}" ]; then - pulls="${{ inputs.pulls }}" - elif [ "${{ github.event_name }}" == "workflow_dispatch" ] || [ "${{ github.event_name }}" == "schedule" ]; then - pulls="${{ needs.poll-pull-requests.outputs.pulls }}" - else - pulls="${{ github.event.number }}" - fi - echo "pulls=$pulls" >> $GITHUB_OUTPUT - echo "Processing pull requests: $pulls" - - - name: "Restore pulls model from cache" - id: restore-model - if: ${{ steps.determine-pulls.outputs.pulls != '' }} - uses: dotnet/issue-labeler/restore@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: pulls - fail-on-cache-miss: ${{ env.ALLOW_FAILURE }} - quiet: true - - - name: "Predict pull labels" - id: prediction - if: ${{ steps.determine-pulls.outputs.pulls != '' && steps.restore-model.outputs.cache-hit == 'true' }} - uses: dotnet/issue-labeler/predict@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - pulls: ${{ steps.determine-pulls.outputs.pulls }} - label_prefix: ${{ env.LABEL_PREFIX }} - threshold: ${{ env.THRESHOLD }} - default_label: ${{ env.DEFAULT_LABEL }} - env: - GITHUB_TOKEN: ${{ github.token }} - continue-on-error: ${{ !env.ALLOW_FAILURE }} diff --git a/.github/workflows/labeler-promote.yml b/.github/workflows/labeler-promote.yml deleted file mode 100644 index c01086c51779..000000000000 --- a/.github/workflows/labeler-promote.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Workflow template imported and updated from: -# https://github.com/dotnet/issue-labeler/wiki/Onboarding -# -# See labeler.md for more information -# -# Promote a model from staging to 'ACTIVE', backing up the currently 'ACTIVE' model -name: "Labeler: Promotion" - -on: - # Dispatched via the Actions UI, promotes the staged models from - # a staged slot into the prediction environment - workflow_dispatch: - inputs: - issues: - description: "Issues: Promote Model" - type: boolean - required: true - pulls: - description: "Pulls: Promote Model" - type: boolean - required: true - staged_key: - description: "The cache key suffix to use for promoting a staged model to 'ACTIVE'. Defaults to 'staged'." - required: true - default: "staged" - backup_key: - description: "The cache key suffix to use for backing up the currently active model. Defaults to 'backup'." - default: "backup" - -permissions: - actions: write - -jobs: - promote-issues: - if: ${{ inputs.issues }} - runs-on: ubuntu-latest - steps: - - name: "Promote Model for Issues" - uses: dotnet/issue-labeler/promote@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "issues" - staged_key: ${{ inputs.staged_key }} - backup_key: ${{ inputs.backup_key }} - - promote-pulls: - if: ${{ inputs.pulls }} - runs-on: ubuntu-latest - steps: - - name: "Promote Model for Pull Requests" - uses: dotnet/issue-labeler/promote@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "pulls" - staged_key: ${{ inputs.staged_key }} - backup_key: ${{ inputs.backup_key }} diff --git a/.github/workflows/labeler-train.yml b/.github/workflows/labeler-train.yml deleted file mode 100644 index 79ad2db0cced..000000000000 --- a/.github/workflows/labeler-train.yml +++ /dev/null @@ -1,161 +0,0 @@ -# Workflow template imported and updated from: -# https://github.com/dotnet/issue-labeler/wiki/Onboarding -# -# See labeler.md for more information -# -# Train the Issues and Pull Requests models for label prediction -name: "Labeler: Training" - -on: - workflow_dispatch: - inputs: - type: - description: "Issues or Pull Requests" - type: choice - required: true - default: "Both" - options: - - "Both" - - "Issues" - - "Pull Requests" - - steps: - description: "Training Steps" - type: choice - required: true - default: "All" - options: - - "All" - - "Download Data" - - "Train Model" - - "Test Model" - - limit: - description: "Max number of items to download for training/testing the model (newest items are used). Defaults to the max number of pages times the page size." - type: number - page_size: - description: "Number of items per page in GitHub API requests. Defaults to 100 for issues, 25 for pull requests." - type: number - page_limit: - description: "Maximum number of pages to download for training/testing the model. Defaults to 1000 for issues, 4000 for pull requests." - type: number - cache_key_suffix: - description: "The cache key suffix to use for staged data/models (use 'ACTIVE' to bypass staging). Defaults to 'staged'." - required: true - default: "staged" - -env: - CACHE_KEY: ${{ inputs.cache_key_suffix }} - REPOSITORY: ${{ github.repository }} - LABEL_PREFIX: "area-" - THRESHOLD: "0.40" - LIMIT: ${{ inputs.limit }} - PAGE_SIZE: ${{ inputs.page_size }} - PAGE_LIMIT: ${{ inputs.page_limit }} - -jobs: - download-issues: - if: ${{ contains(fromJSON('["Both", "Issues"]'), inputs.type) && contains(fromJSON('["All", "Download Data"]'), inputs.steps) }} - runs-on: ubuntu-latest - permissions: - issues: read - steps: - - name: "Download Issues" - uses: dotnet/issue-labeler/download@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "issues" - cache_key: ${{ env.CACHE_KEY }} - repository: ${{ env.REPOSITORY }} - label_prefix: ${{ env.LABEL_PREFIX }} - limit: ${{ env.LIMIT }} - page_size: ${{ env.PAGE_SIZE }} - page_limit: ${{ env.PAGE_LIMIT }} - env: - GITHUB_TOKEN: ${{ github.token }} - - download-pulls: - if: ${{ contains(fromJSON('["Both", "Pull Requests"]'), inputs.type) && contains(fromJSON('["All", "Download Data"]'), inputs.steps) }} - runs-on: ubuntu-latest - permissions: - pull-requests: read - steps: - - name: "Download Pull Requests" - uses: dotnet/issue-labeler/download@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "pulls" - cache_key: ${{ env.CACHE_KEY }} - repository: ${{ env.REPOSITORY }} - label_prefix: ${{ env.LABEL_PREFIX }} - limit: ${{ env.LIMIT }} - page_size: ${{ env.PAGE_SIZE }} - page_limit: ${{ env.PAGE_LIMIT }} - env: - GITHUB_TOKEN: ${{ github.token }} - - train-issues: - if: ${{ always() && contains(fromJSON('["Both", "Issues"]'), inputs.type) && contains(fromJSON('["All", "Train Model"]'), inputs.steps) && contains(fromJSON('["success", "skipped"]'), needs.download-issues.result) }} - runs-on: ubuntu-latest - permissions: {} - needs: download-issues - steps: - - name: "Train Model for Issues" - uses: dotnet/issue-labeler/train@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "issues" - data_cache_key: ${{ env.CACHE_KEY }} - model_cache_key: ${{ env.CACHE_KEY }} - - train-pulls: - if: ${{ always() && contains(fromJSON('["Both", "Pull Requests"]'), inputs.type) && contains(fromJSON('["All", "Train Model"]'), inputs.steps) && contains(fromJSON('["success", "skipped"]'), needs.download-pulls.result) }} - runs-on: ubuntu-latest - permissions: {} - needs: download-pulls - steps: - - name: "Train Model for Pull Requests" - uses: dotnet/issue-labeler/train@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "pulls" - data_cache_key: ${{ env.CACHE_KEY }} - model_cache_key: ${{ env.CACHE_KEY }} - - test-issues: - if: ${{ always() && contains(fromJSON('["Both", "Issues"]'), inputs.type) && contains(fromJSON('["All", "Test Model"]'), inputs.steps) && contains(fromJSON('["success", "skipped"]'), needs.train-issues.result) }} - runs-on: ubuntu-latest - permissions: - issues: read - needs: train-issues - steps: - - name: "Test Model for Issues" - uses: dotnet/issue-labeler/test@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "issues" - cache_key: ${{ env.CACHE_KEY }} - repository: ${{ env.REPOSITORY }} - label_prefix: ${{ env.LABEL_PREFIX }} - threshold: ${{ env.THRESHOLD }} - limit: ${{ env.LIMIT }} - page_size: ${{ env.PAGE_SIZE }} - page_limit: ${{ env.PAGE_LIMIT }} - env: - GITHUB_TOKEN: ${{ github.token }} - - test-pulls: - if: ${{ always() && contains(fromJSON('["Both", "Pull Requests"]'), inputs.type) && contains(fromJSON('["All", "Test Model"]'), inputs.steps) && contains(fromJSON('["success", "skipped"]'), needs.train-pulls.result) }} - runs-on: ubuntu-latest - permissions: - pull-requests: read - needs: train-pulls - steps: - - name: "Test Model for Pull Requests" - uses: dotnet/issue-labeler/test@46125e85e6a568dc712f358c39f35317366f5eed # v2.0.0 - with: - type: "pulls" - cache_key: ${{ env.CACHE_KEY }} - repository: ${{ env.REPOSITORY }} - label_prefix: ${{ env.LABEL_PREFIX }} - threshold: ${{ env.THRESHOLD }} - limit: ${{ env.LIMIT }} - page_size: ${{ env.PAGE_SIZE }} - page_limit: ${{ env.PAGE_LIMIT }} - env: - GITHUB_TOKEN: ${{ github.token }}