ray-project/ray

4 workflows · maturity 0% · 0 patterns · GitHub ↗

Security 0/100

Practices

○ Matrix○ Permissions○ Security scan○ AI review○ Cache○ Concurrency○ Reusable workflows

Security dimensions

permissions
0
security scan
0
supply chain
0
secret handling
0
harden runner
0

Workflows (4)

notify-slack-on-label .github/workflows/notify-slack-on-label.yml
Triggers
issues, pull_request
Runs on
ubuntu-latest
Jobs
notify
View raw YAML
name: Notify Slack on Labeled Issue or PR

on:
  issues:
    types: [labeled]
  pull_request:
    types: [labeled]

jobs:
  notify:
    runs-on: ubuntu-latest
    steps:
      - name: Notify Slack Channel Based on Label
        uses: actions/github-script@v7
        with:
          script: |
            // ── Label → Slack webhook secret name mapping ──────────────────────
            // Add or remove entries here as you add/remove Ray library channels.
            // The key is the GitHub label name; the value is the name of the
            // GitHub Actions secret that holds that channel's Incoming Webhook URL.
            const LABEL_TO_SECRET = {
              "serve":        "SLACK_WEBHOOK_SERVE",
              "train":        "SLACK_WEBHOOK_TRAIN",
              "tune":         "SLACK_WEBHOOK_TUNE",
              "rllib":        "SLACK_WEBHOOK_RLLIB",
              "data":         "SLACK_WEBHOOK_DATA",
              "air":          "SLACK_WEBHOOK_AIR",
              "core":         "SLACK_WEBHOOK_CORE",
              "workflow":     "SLACK_WEBHOOK_WORKFLOW",
              "cluster":      "SLACK_WEBHOOK_CLUSTER",
            };

            // ── Resolve the webhook URLs from secrets ──────────────────────────
            // We pass secrets in as env vars so the script can read them safely.
            const SECRET_VALUES = {
              "SLACK_WEBHOOK_SERVE":    process.env.SLACK_WEBHOOK_SERVE,
              "SLACK_WEBHOOK_TRAIN":    process.env.SLACK_WEBHOOK_TRAIN,
              "SLACK_WEBHOOK_TUNE":     process.env.SLACK_WEBHOOK_TUNE,
              "SLACK_WEBHOOK_RLLIB":    process.env.SLACK_WEBHOOK_RLLIB,
              "SLACK_WEBHOOK_DATA":     process.env.SLACK_WEBHOOK_DATA,
              "SLACK_WEBHOOK_AIR":      process.env.SLACK_WEBHOOK_AIR,
              "SLACK_WEBHOOK_CORE":     process.env.SLACK_WEBHOOK_CORE,
              "SLACK_WEBHOOK_WORKFLOW": process.env.SLACK_WEBHOOK_WORKFLOW,
              "SLACK_WEBHOOK_CLUSTER":  process.env.SLACK_WEBHOOK_CLUSTER,
            };

            // ── Determine event type and payload ──────────────────────────────
            const isPR    = !!context.payload.pull_request;
            const item    = isPR ? context.payload.pull_request : context.payload.issue;
            const type    = isPR ? "Pull Request" : "Issue";
            const action  = context.payload.action;           // "opened" | "labeled"
            const labels  = (item.labels || []).map(l => l.name);

            // On "labeled" events, only act on the label that was just added
            // (avoids duplicate messages when multiple labels already exist).
            const triggeredLabel = action === "labeled"
              ? context.payload.label.name
              : null;

            const labelsToProcess = triggeredLabel ? [triggeredLabel] : labels;

            // ── Send a message for each matching label ─────────────────────────
            for (const label of labelsToProcess) {
              const secretName = LABEL_TO_SECRET[label];
              if (!secretName) continue;                      // label not mapped

              const webhookUrl = SECRET_VALUES[secretName];
              if (!webhookUrl) {
                core.warning(`Secret ${secretName} is not set — skipping #${label}`);
                continue;
              }

              // Build a rich Slack Block Kit message
              const allLabelNames = labels.map(l => `\`${l}\``).join(" ");
              const body = {
                blocks: [
                  {
                    type: "section",
                    text: {
                      type: "mrkdwn",
                      text: `*New ${type} in <https://github.com/${context.repo.owner}/${context.repo.repo}|${context.repo.owner}/${context.repo.repo}>*`
                    }
                  },
                  {
                    type: "section",
                    fields: [
                      { type: "mrkdwn", text: `*Title*\n<${item.html_url}|${item.title}>` },
                      { type: "mrkdwn", text: `*Author*\n<${item.user.html_url}|${item.user.login}>` },
                      { type: "mrkdwn", text: `*Labels*\n${allLabelNames || "_none_"}` },
                      { type: "mrkdwn", text: `*#*\n${item.number}` },
                    ]
                  },
                  ...(item.body ? [{
                    type: "section",
                    text: {
                      type: "mrkdwn",
                      // Truncate long bodies so the message stays readable
                      text: `*Description*\n${item.body.slice(0, 300)}${item.body.length > 300 ? "…" : ""}`
                    }
                  }] : []),
                  {
                    type: "actions",
                    elements: [
                      {
                        type: "button",
                        text: { type: "plain_text", text: `View ${type}` },
                        url: item.html_url,
                        style: "primary"
                      }
                    ]
                  }
                ]
              };

              const response = await fetch(webhookUrl, {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify(body)
              });

              if (!response.ok) {
                core.error(`Failed to post to Slack for label "${label}": ${response.status} ${response.statusText}`);
              } else {
                core.info(`Posted to Slack channel for label "${label}"`);
              }
            }
        env:
          SLACK_WEBHOOK_SERVE:    ${{ secrets.SLACK_WEBHOOK_SERVE }}
          SLACK_WEBHOOK_TRAIN:    ${{ secrets.SLACK_WEBHOOK_TRAIN }}
          SLACK_WEBHOOK_TUNE:     ${{ secrets.SLACK_WEBHOOK_TUNE }}
          SLACK_WEBHOOK_RLLIB:    ${{ secrets.SLACK_WEBHOOK_RLLIB }}
          SLACK_WEBHOOK_DATA:     ${{ secrets.SLACK_WEBHOOK_DATA }}
          SLACK_WEBHOOK_AIR:      ${{ secrets.SLACK_WEBHOOK_AIR }}
          SLACK_WEBHOOK_CORE:     ${{ secrets.SLACK_WEBHOOK_CORE }}
          SLACK_WEBHOOK_WORKFLOW: ${{ secrets.SLACK_WEBHOOK_WORKFLOW }}
          SLACK_WEBHOOK_CLUSTER:  ${{ secrets.SLACK_WEBHOOK_CLUSTER }}
on_auto_merge .github/workflows/on_auto_merge.yaml
Triggers
pull_request_target
Runs on
ubuntu-latest
Jobs
add-go-label
View raw YAML
name: Auto merge enabled
on:
  pull_request_target:
    types:
      - auto_merge_enabled
jobs:
  add-go-label:
    runs-on: ubuntu-latest
    steps:
      - name: Add go label
        uses: actions/github-script@v5
        with:
          script: |
            github.rest.issues.addLabels({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              labels: ['go']
            })
on_pull_request_synchronized .github/workflows/on_pull_request_synchronized.yml
Triggers
pull_request_target
Runs on
ubuntu-latest
Jobs
disable-automerge
View raw YAML
name: Pull request synchronized
on:
  pull_request_target:
    types:
      - synchronize
    branches:
      - "master"
      - "releases/**"
jobs:
  disable-automerge:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v7
        with:
          script: |
            const prQuery = `query PullRequest($owner: String!, $repo: String!, $pullRequestNumber: Int!) {
              repository(owner: $owner, name: $repo) {
                pullRequest(number: $pullRequestNumber) {
                  id
                  autoMergeRequest {
                    enabledAt
                  }
                }
              }
            }`;
            const prVariables = {
              owner: context.repo.owner,
              repo: context.repo.repo,
              pullRequestNumber: context.issue.number
            }
            const prResult = await github.graphql(prQuery, prVariables)
            if (!prResult.repository.pullRequest.autoMergeRequest) {
              console.log('Auto merge is not enabled')
              return
            }
            const automergeQuery = `mutation DisablePullRequestAutoMerge($pullRequestId: ID!) {
              disablePullRequestAutoMerge(input: {pullRequestId: $pullRequestId}) {
                pullRequest {
                  id
                }
              }
            }`;
            const automergeVariables = {
              pullRequestId: prResult.repository.pullRequest.id
            }
            const result = await github.graphql(automergeQuery, automergeVariables)
            console.log(result)
stale_pull_request .github/workflows/stale_pull_request.yaml
Triggers
schedule
Runs on
ubuntu-latest
Jobs
stale
Actions
actions/stale
View raw YAML
name: Mark and Close Stale Pull Requests

on:
  schedule:
    # Runs twice a day at 15 minutes past midnight and noon UTC
    - cron: '15 */12 * * *'

jobs:
  stale:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write # Required to add labels, comment, close PRs.

    steps:
      - name: Mark and Close Stale Pull Requests
        uses: actions/stale@v9
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

          # --- Ignore Issues ---
          # Set to -1 so we never mark issues as stale or closed.
          days-before-issue-stale: -1
          days-before-issue-close: -1

          # --- Pull Request Specific Settings ---
          # Number of days of inactivity before a Pull Request becomes stale (currently 2 weeks)
          days-before-pr-stale: 14

          # Number of days of inactivity after being marked stale before a Pull Request is closed (2 more weeks)
          days-before-pr-close: 14

          # Label to use when marking a PR as stale
          stale-pr-label: 'stale'

          # Comment to post when marking a PR as stale
          stale-pr-message: |
            This pull request has been automatically marked as stale because it has not had
            any activity for 14 days. It will be closed in another 14 days if no further activity occurs.
            Thank you for your contributions.

            You can always ask for help on our [discussion forum](https://discuss.ray.io/) or [Ray's public slack channel](https://github.com/ray-project/ray#getting-involved).

            If you'd like to keep this open, just leave any comment, and the stale label will be removed.

          # Comment to post when closing a stale PR
          close-pr-message: |
            This pull request has been automatically closed because there has been no more activity in the 14 days
            since being marked stale.

            Please feel free to reopen or open a new pull request if you'd still like this to be addressed.

            Again, you can always ask for help on our [discussion forum](https://discuss.ray.io) or [Ray's public slack channel](https://github.com/ray-project/ray#getting-involved).

            Thanks again for your contribution!

          # Pull Requests with these labels will never be considered stale
          exempt-pr-labels: >
            weekly-release-blocker,
            release-blocker,
            unstale

          # Set to true to ignore PRs in a milestone (defaults to false)
          exempt-all-pr-milestones: true

          # --- Shared Settings & Other Options ---
          # Limit the number of actions per run.
          operations-per-run: 500

          # Remove stale label from PRs on update (default is true)
          remove-pr-stale-when-updated: true

          # Add unstale label. Whenever a PR is marked as 'unstale' it will not be marked stale again.
          labels-to-add-when-unstale: unstale

          ascending: true