continuedev/continue

30 workflows · maturity 67% · 12 patterns · GitHub ↗

Security 19.17/100

Security dimensions

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

Workflows (30)

auto-assign-issue .github/workflows/auto-assign-issue.yaml
Triggers
issues
Runs on
ubuntu-latest
Jobs
auto-assign
Actions
pozil/auto-assign-issue
View raw YAML
name: Issue assignment

on:
  issues:
    types: [opened]

jobs:
  auto-assign:
    runs-on: ubuntu-latest
    permissions:
      issues: write
    steps:
      - name: "Auto-assign issue"
        uses: pozil/auto-assign-issue@v2
        with:
          repo-token: ${{ secrets.CI_GITHUB_TOKEN }}
          assignees: Patrick-Erichsen,tomasz-stefaniak,RomneyDa,tingwai,uinstinct
          numOfAssignee: 1
      # - name: "Add default labels"
      #   uses: actions-ecosystem/action-add-labels@v1
      #   with:
      #     github_token: ${{ secrets.GITHUB_TOKEN }}
      #     labels: |
      #       "needs-triage"
auto-fix-failed-tests perms .github/workflows/auto-fix-failed-tests.yml
Triggers
workflow_run
Runs on
ubuntu-latest
Jobs
fix-failed-tests
Commands
  • npm i -g @continuedev/cli
  • # Create a detailed prompt for fixing the failed tests cat > /tmp/fix_tests_prompt.txt << 'PROMPT_EOF' 🔧 **Auto Test Fix Request** The following tests failed in workflow "${{ steps.workflow-details.outputs.workflow_name }}" (Run ID: ${{ steps.workflow-details.outputs.workflow_run_id }}): **Failed Jobs:** ${{ steps.workflow-details.outputs.failed_jobs }} **Branch:** ${{ steps.workflow-details.outputs.head_branch }} **Commit:** ${{ steps.workflow-details.outputs.head_sha }} **Your Task:** 1. Analyze the test failure logs and error messages 2. Identify the root cause of the test failures 3. Fix the failing tests by updating the test code or the underlying implementation 4. Ensure all tests pass after your changes 5. Commit your fixes with a descriptive message **Test Failure Context:** Please examine the repository structure, run the failing tests locally to understand the errors, and implement appropriate fixes. Focus on: - Understanding what the tests are trying to validate - Identifying why they're failing (code changes, environment issues, test logic errors) - Making minimal, targeted fixes that address the root cause - Ensuring the fixes don't break other functionality Please start by examining the failing tests and their error messages, then proceed with the necessary fixes. PROMPT_EOF echo "Starting Continue CLI remote session for test fixes..." echo "Prompt content:" cat /tmp/fix_tests_prompt.txt # Start remote session and capture JSON output SESSION_OUTPUT=$(cat /tmp/fix_tests_prompt.txt | cn remote -s --branch ${{ steps.workflow-details.outputs.head_branch }}) echo "Raw session output: $SESSION_OUTPUT" # Extract URL from JSON output SESSION_URL=$(echo "$SESSION_OUTPUT" | jq -r '.url // empty') if [ -z "$SESSION_URL" ] || [ "$SESSION_URL" = "null" ]; then echo "Failed to extract session URL from output: $SESSION_OUTPUT" exit 1 fi echo "session_url=$SESSION_URL" >> $GITHUB_OUTPUT echo "✅ Started remote session: $SESSION_URL"
  • echo "✅ Successfully started auto-fix session for failed tests" echo "Workflow: ${{ steps.workflow-details.outputs.workflow_name }}" echo "Run ID: ${{ steps.workflow-details.outputs.workflow_run_id }}" echo "Branch: ${{ steps.workflow-details.outputs.head_branch }}" echo "Session URL: ${{ steps.remote-session.outputs.session_url }}" echo "Failed jobs: ${{ steps.workflow-details.outputs.failed_jobs }}"
View raw YAML
name: Auto Fix Failed Tests

on:
  workflow_run:
    workflows: ["PR Checks", "CLI PR Checks"]
    types:
      - completed

permissions:
  contents: write
  pull-requests: write
  issues: write
  actions: read

jobs:
  fix-failed-tests:
    # Only run if the workflow failed
    # DISABLED: Remove 'false && ' on the next line to enable auto-fixing
    if: false && github.event.workflow_run.conclusion == 'failure'
    runs-on: ubuntu-latest

    steps:
      - name: Get workflow run details
        id: workflow-details
        uses: actions/github-script@v8
        with:
          script: |
            const workflowRun = context.payload.workflow_run;
            const { data: jobs } = await github.rest.actions.listJobsForWorkflowRun({
              owner: context.repo.owner,
              repo: context.repo.repo,
              run_id: workflowRun.id
            });

            // Find all failed jobs since we're only monitoring specific test workflows
            const failedJobs = jobs.jobs.filter(job => job.conclusion === 'failure');

            if (failedJobs.length === 0) {
              core.info('No failed jobs found');
              return null;
            }

            core.setOutput('has_failed_tests', 'true');
            core.setOutput('workflow_name', workflowRun.name);
            core.setOutput('workflow_run_id', workflowRun.id);
            core.setOutput('head_branch', workflowRun.head_branch);
            core.setOutput('head_sha', workflowRun.head_sha);
            core.setOutput('failed_jobs', JSON.stringify(failedJobs.map(j => j.name)));

            return failedJobs;

      - name: Get job logs for failed tests
        if: steps.workflow-details.outputs.has_failed_tests == 'true'
        id: get-logs
        uses: actions/github-script@v8
        with:
          script: |
            const workflowRunId = ${{ github.event.workflow_run.id }};
            const { data: jobs } = await github.rest.actions.listJobsForWorkflowRun({
              owner: context.repo.owner,
              repo: context.repo.repo,
              run_id: workflowRunId
            });

            let errorLogs = '';

            for (const job of jobs.jobs) {
              if (job.conclusion === 'failure') {
                try {
                  const { data: logData } = await github.rest.actions.downloadJobLogsForWorkflowRun({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    job_id: job.id
                  });
                  
                  errorLogs += `\n\n=== Job: ${job.name} ===\n`;
                  errorLogs += logData;
                } catch (error) {
                  core.warning(`Could not fetch logs for job ${job.name}: ${error.message}`);
                }
              }
            }

            // Store logs in environment file for next step
            const fs = require('fs');
            fs.writeFileSync('/tmp/test_failure_logs.txt', errorLogs);

            core.setOutput('has_logs', errorLogs.length > 0 ? 'true' : 'false');

      - name: Checkout repository
        if: steps.workflow-details.outputs.has_failed_tests == 'true'
        uses: actions/checkout@v6
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0
          ref: ${{ steps.workflow-details.outputs.head_sha }}

      - name: Setup Node.js
        if: steps.workflow-details.outputs.has_failed_tests == 'true'
        uses: actions/setup-node@v6
        with:
          node-version: "20"

      - name: Install Continue CLI globally
        if: steps.workflow-details.outputs.has_failed_tests == 'true'
        run: npm i -g @continuedev/cli

      - name: Start remote session to fix failed tests
        if: steps.workflow-details.outputs.has_failed_tests == 'true'
        id: remote-session
        env:
          CONTINUE_API_KEY: ${{ secrets.CONTINUE_API_KEY }}
        run: |
          # Create a detailed prompt for fixing the failed tests
          cat > /tmp/fix_tests_prompt.txt << 'PROMPT_EOF'
          🔧 **Auto Test Fix Request**

          The following tests failed in workflow "${{ steps.workflow-details.outputs.workflow_name }}" (Run ID: ${{ steps.workflow-details.outputs.workflow_run_id }}):

          **Failed Jobs:** ${{ steps.workflow-details.outputs.failed_jobs }}
          **Branch:** ${{ steps.workflow-details.outputs.head_branch }}
          **Commit:** ${{ steps.workflow-details.outputs.head_sha }}

          **Your Task:**
          1. Analyze the test failure logs and error messages
          2. Identify the root cause of the test failures
          3. Fix the failing tests by updating the test code or the underlying implementation
          4. Ensure all tests pass after your changes
          5. Commit your fixes with a descriptive message

          **Test Failure Context:**
          Please examine the repository structure, run the failing tests locally to understand the errors, and implement appropriate fixes.

          Focus on:
          - Understanding what the tests are trying to validate
          - Identifying why they're failing (code changes, environment issues, test logic errors)
          - Making minimal, targeted fixes that address the root cause
          - Ensuring the fixes don't break other functionality

          Please start by examining the failing tests and their error messages, then proceed with the necessary fixes.
          PROMPT_EOF

          echo "Starting Continue CLI remote session for test fixes..."
          echo "Prompt content:"
          cat /tmp/fix_tests_prompt.txt

          # Start remote session and capture JSON output
          SESSION_OUTPUT=$(cat /tmp/fix_tests_prompt.txt | cn remote -s --branch ${{ steps.workflow-details.outputs.head_branch }})
          echo "Raw session output: $SESSION_OUTPUT"

          # Extract URL from JSON output
          SESSION_URL=$(echo "$SESSION_OUTPUT" | jq -r '.url // empty')

          if [ -z "$SESSION_URL" ] || [ "$SESSION_URL" = "null" ]; then
            echo "Failed to extract session URL from output: $SESSION_OUTPUT"
            exit 1
          fi

          echo "session_url=$SESSION_URL" >> $GITHUB_OUTPUT
          echo "✅ Started remote session: $SESSION_URL"

      - name: Log session details
        if: steps.workflow-details.outputs.has_failed_tests == 'true'
        run: |
          echo "✅ Successfully started auto-fix session for failed tests"
          echo "Workflow: ${{ steps.workflow-details.outputs.workflow_name }}"
          echo "Run ID: ${{ steps.workflow-details.outputs.workflow_run_id }}"
          echo "Branch: ${{ steps.workflow-details.outputs.head_branch }}"
          echo "Session URL: ${{ steps.remote-session.outputs.session_url }}"
          echo "Failed jobs: ${{ steps.workflow-details.outputs.failed_jobs }}"
auto-release .github/workflows/auto-release.yml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest, ubuntu-latest
Jobs
create-vscode-release, create-jetbrains-release
Commands
  • # Read version from package.json and add -vscode suffix version=$(node -p "require('./extensions/vscode/package.json').version") new_version="v${version}-vscode" echo "New version will be: $new_version" echo "NEW_VERSION=$new_version" >> $GITHUB_ENV
  • # Create a new draft release with auto-generated release notes gh release create "$NEW_VERSION" \ --generate-notes \ --title "$NEW_VERSION" \ --draft \ --latest \ --prerelease
  • # Read version from gradle.properties and add -jetbrains suffix version=$(grep '^pluginVersion=' extensions/intellij/gradle.properties | cut -d'=' -f2) new_version="v${version}-jetbrains" echo "New version will be: $new_version" echo "NEW_VERSION=$new_version" >> $GITHUB_ENV
  • # Create a new draft release with auto-generated release notes gh release create "$NEW_VERSION" \ --generate-notes \ --title "$NEW_VERSION" \ --draft \ --latest \ --prerelease
View raw YAML
name: Create Automatic Release

on:
  push:
    branches:
      - nate/auto-main-release-draft
  # Not using this now because making drafts was just noisy. Will be useful when we are ready for automated releases.
  # schedule:
  #   - cron: "0 17 * * 1,3,5" # Run at 9am PST (17:00 UTC) on Monday, Wednesday, Friday
  workflow_dispatch: # Keep manual trigger option

jobs:
  create-vscode-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write # Needed for creating releases

    steps:
      - uses: actions/checkout@v6

      - name: Get version from package.json
        id: get_version
        run: |
          # Read version from package.json and add -vscode suffix
          version=$(node -p "require('./extensions/vscode/package.json').version")
          new_version="v${version}-vscode"
          echo "New version will be: $new_version"
          echo "NEW_VERSION=$new_version" >> $GITHUB_ENV

      - name: Create Release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          # Create a new draft release with auto-generated release notes
          gh release create "$NEW_VERSION" \
            --generate-notes \
            --title "$NEW_VERSION" \
            --draft \
            --latest \
            --prerelease

  create-jetbrains-release:
    runs-on: ubuntu-latest
    permissions:
      contents: write # Needed for creating releases

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Get version from gradle.properties
        id: get_version
        run: |
          # Read version from gradle.properties and add -jetbrains suffix
          version=$(grep '^pluginVersion=' extensions/intellij/gradle.properties | cut -d'=' -f2)
          new_version="v${version}-jetbrains"
          echo "New version will be: $new_version"
          echo "NEW_VERSION=$new_version" >> $GITHUB_ENV

      - name: Create Release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          # Create a new draft release with auto-generated release notes
          gh release create "$NEW_VERSION" \
            --generate-notes \
            --title "$NEW_VERSION" \
            --draft \
            --latest \
            --prerelease
cla perms .github/workflows/cla.yaml
Triggers
issue_comment, pull_request_target
Runs on
ubuntu-latest
Jobs
CLAAssistant
Actions
contributor-assistant/github-action
View raw YAML
name: "CLA Assistant"
on:
  issue_comment:
    types: [created]
  pull_request_target:
    types: [opened, closed, synchronize]

permissions:
  actions: write
  contents: write
  pull-requests: write
  statuses: write

jobs:
  CLAAssistant:
    runs-on: ubuntu-latest
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    steps:
      - name: "CLA Assistant"
        if: (contains(github.event.comment.body, 'recheck') || contains(github.event.comment.body, 'I have read the CLA Document and I hereby sign the CLA')) || github.event_name == 'pull_request_target'
        uses: contributor-assistant/github-action@v2.6.1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          path-to-signatures: "signatures/version1/cla.json"
          path-to-document: "https://github.com/continuedev/continue/blob/main/CLA.md"
          branch: cla-signatures
          # Bots and CLAs signed outside of GitHub
          allowlist: dependabot[bot],fbricon,panyamkeerthana,Jazzcort,owtaylor,halfline,agent@continue.dev,action@github.com,continue[bot],snyk-bot,noreply@continue.dev,google-labs-jules[bot]
          signed-commit-message: "CLA signed in $pullRequestNo"
cli-pr-checks matrix perms .github/workflows/cli-pr-checks.yml
Triggers
pull_request
Runs on
ubuntu-latest, ubuntu-latest, ${{ matrix.os }}, ubuntu-latest, ubuntu-latest
Jobs
track-rerun, lint, test, smoke-api, require-all-checks-to-pass-cli
Matrix
node-version, os→ 18, 20, 22, 24, macos-latest, ubuntu-latest, windows-latest
Actions
re-actors/alls-green
Commands
  • cd core npm run build
  • cd extensions/cli npm ci --include=optional
  • cd extensions/cli npm run lint
  • cd core npm run build
  • cd extensions/cli npm ci --include=optional
  • cd extensions/cli npm run build
  • cd extensions/cli npm run test:smoke
  • cd extensions/cli npm test
View raw YAML
name: CLI PR Checks

on:
  pull_request:
    branches: [main]

permissions:
  contents: read
  pull-requests: write
  issues: write

jobs:
  track-rerun:
    runs-on: ubuntu-latest
    if: github.run_attempt > 1
    steps:
      - uses: actions/checkout@v6
      - name: Track workflow rerun
        uses: ./.github/actions/track-rerun

  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 20
          cache: "npm"
          cache-dependency-path: extensions/cli/package-lock.json

      - name: Setup packages
        uses: ./.github/actions/setup-packages
      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true

      - name: Build core
        run: |
          cd core
          npm run build

      - name: Install dependencies
        run: |
          cd extensions/cli
          npm ci --include=optional

      - name: Run linting
        run: |
          cd extensions/cli
          npm run lint

  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node-version: [18, 20, 22, 24]
      fail-fast: false
    runs-on: ${{ matrix.os }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v6
        with:
          node-version: ${{ matrix.node-version }}

      - name: Cache CLI node_modules
        uses: actions/cache@v5
        with:
          path: extensions/cli/node_modules
          key: ${{ runner.os }}-node${{ matrix.node-version }}-cli-modules-${{ hashFiles('extensions/cli/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node${{ matrix.node-version }}-cli-modules-

      - name: Setup packages
        uses: ./.github/actions/setup-packages
      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true

      - name: Build core
        run: |
          cd core
          npm run build

      - name: Install dependencies
        run: |
          cd extensions/cli
          npm ci --include=optional

      - name: Build
        run: |
          cd extensions/cli
          npm run build

      - name: Run smoke tests
        run: |
          cd extensions/cli
          npm run test:smoke

      - name: Run tests
        run: |
          cd extensions/cli
          npm test

      # e2e tests are failing on Windows specifically - likely due to stdout flush issues
      - name: Run e2e tests
        if: matrix.os != 'windows-latest'
        run: |
          cd extensions/cli
          npm run test:e2e

  smoke-api:
    # Only runs when secrets are available (not on fork PRs)
    if: github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 20
          cache: "npm"
          cache-dependency-path: extensions/cli/package-lock.json

      - name: Setup packages
        uses: ./.github/actions/setup-packages
      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true

      - name: Build core
        run: |
          cd core
          npm run build

      - name: Install dependencies
        run: |
          cd extensions/cli
          npm ci --include=optional

      - name: Build
        run: |
          cd extensions/cli
          npm run build

      - name: Run smoke API tests
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          CONTINUE_API_KEY: ${{ secrets.CONTINUE_API_KEY }}
        run: |
          cd extensions/cli
          npm run test:smoke-api

  # GitHub does not have a way of requiring that all checks pass (you must manually select each job)
  # This action at least lets us manage the list of required tests via source control
  # so that creators of new jobs can add them to this list
  require-all-checks-to-pass-cli:
    if: always()
    runs-on: ubuntu-latest
    needs:
      - lint
      - test
      - smoke-api

    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        with:
          # smoke-api is allowed to skip for fork PRs that lack secrets
          allowed-skips: smoke-api
          jobs: ${{ toJSON(needs) }}
continue-agents matrix perms .github/workflows/continue-agents.yml
Triggers
workflow_call
Runs on
ubuntu-latest, ubuntu-latest
Jobs
discover, run-agent
Matrix
agent→ ${{ fromJson(needs.discover.outputs.matrix) }}
Commands
  • AGENTS_DIR="${{ inputs.agents-path }}" if [ -d "$AGENTS_DIR" ]; then # Use -sc for compact single-line JSON (required for GitHub Actions output) FILES=$(find "$AGENTS_DIR" -name "*.md" -type f 2>/dev/null | jq -R . | jq -sc .) COUNT=$(echo "$FILES" | jq 'length') HAS_AGENTS=$([[ $COUNT -gt 0 ]] && echo "true" || echo "false") else FILES="[]" COUNT=0 HAS_AGENTS="false" fi echo "matrix=$FILES" >> $GITHUB_OUTPUT echo "has_agents=$HAS_AGENTS" >> $GITHUB_OUTPUT echo "Found $COUNT agent(s)"
  • npm i -g @continuedev/cli
  • AGENT_FILE="${{ matrix.agent }}" AGENT_NAME=$(basename "$AGENT_FILE" .md) echo "name=$AGENT_NAME" >> $GITHUB_OUTPUT
  • AGENT_FILE="${{ matrix.agent }}" # Run agent in non-interactive mode (-p flag) if OUTPUT=$(cn -p --agent "$AGENT_FILE" 2>&1); then echo "success=true" >> $GITHUB_OUTPUT echo "output<<EOF" >> $GITHUB_OUTPUT echo "$OUTPUT" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT echo "✅ Agent completed successfully" echo "" echo "--- Agent Output ---" echo "$OUTPUT" else echo "success=false" >> $GITHUB_OUTPUT echo "error<<EOF" >> $GITHUB_OUTPUT echo "$OUTPUT" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT echo "❌ Agent failed" echo "" echo "--- Agent Output ---" echo "$OUTPUT" fi
  • echo "## 🤖 Agent: $AGENT_NAME" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY if [ "$AGENT_SUCCESS" == "true" ]; then echo "✅ **Status:** Completed successfully" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Output" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY printf '%s\n' "$AGENT_OUTPUT" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY else echo "❌ **Status:** Failed" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Error" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY printf '%s\n' "$AGENT_ERROR" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY fi
  • exit 1
View raw YAML
name: Continue Agents

on:
  workflow_call:
    inputs:
      agents-path:
        description: 'Path to agents folder'
        required: false
        default: '.continue/agents'
        type: string
    secrets:
      ANTHROPIC_API_KEY:
        description: 'Anthropic API key for Claude'
        required: true

permissions:
  contents: write
  checks: write
  pull-requests: write

jobs:
  discover:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.discover.outputs.matrix }}
      has-agents: ${{ steps.discover.outputs.has_agents }}
    steps:
      - uses: actions/checkout@v6

      - name: Discover agents
        id: discover
        run: |
          AGENTS_DIR="${{ inputs.agents-path }}"
          if [ -d "$AGENTS_DIR" ]; then
            # Use -sc for compact single-line JSON (required for GitHub Actions output)
            FILES=$(find "$AGENTS_DIR" -name "*.md" -type f 2>/dev/null | jq -R . | jq -sc .)
            COUNT=$(echo "$FILES" | jq 'length')
            HAS_AGENTS=$([[ $COUNT -gt 0 ]] && echo "true" || echo "false")
          else
            FILES="[]"
            COUNT=0
            HAS_AGENTS="false"
          fi

          echo "matrix=$FILES" >> $GITHUB_OUTPUT
          echo "has_agents=$HAS_AGENTS" >> $GITHUB_OUTPUT
          echo "Found $COUNT agent(s)"

  run-agent:
    needs: discover
    if: needs.discover.outputs.has-agents == 'true'
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        agent: ${{ fromJson(needs.discover.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v6

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: '20'

      - name: Install Continue CLI
        run: npm i -g @continuedev/cli

      - name: Extract agent name
        id: agent-name
        run: |
          AGENT_FILE="${{ matrix.agent }}"
          AGENT_NAME=$(basename "$AGENT_FILE" .md)
          echo "name=$AGENT_NAME" >> $GITHUB_OUTPUT

      - name: Create Check Run
        id: check
        uses: actions/github-script@v8
        env:
          AGENT_NAME: ${{ steps.agent-name.outputs.name }}
        with:
          script: |
            const { data: check } = await github.rest.checks.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              name: `Continue: ${process.env.AGENT_NAME}`,
              head_sha: context.sha,
              status: 'in_progress',
              started_at: new Date().toISOString(),
            });
            core.setOutput('id', check.id);

      - name: Run agent
        id: run
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GH_TOKEN: ${{ github.token }}
        run: |
          AGENT_FILE="${{ matrix.agent }}"

          # Run agent in non-interactive mode (-p flag)
          if OUTPUT=$(cn -p --agent "$AGENT_FILE" 2>&1); then
            echo "success=true" >> $GITHUB_OUTPUT
            echo "output<<EOF" >> $GITHUB_OUTPUT
            echo "$OUTPUT" >> $GITHUB_OUTPUT
            echo "EOF" >> $GITHUB_OUTPUT
            echo "✅ Agent completed successfully"
            echo ""
            echo "--- Agent Output ---"
            echo "$OUTPUT"
          else
            echo "success=false" >> $GITHUB_OUTPUT
            echo "error<<EOF" >> $GITHUB_OUTPUT
            echo "$OUTPUT" >> $GITHUB_OUTPUT
            echo "EOF" >> $GITHUB_OUTPUT
            echo "❌ Agent failed"
            echo ""
            echo "--- Agent Output ---"
            echo "$OUTPUT"
          fi

      - name: Write job summary
        if: always()
        env:
          AGENT_OUTPUT: ${{ steps.run.outputs.output }}
          AGENT_ERROR: ${{ steps.run.outputs.error }}
          AGENT_SUCCESS: ${{ steps.run.outputs.success }}
          AGENT_NAME: ${{ steps.agent-name.outputs.name }}
        run: |
          echo "## 🤖 Agent: $AGENT_NAME" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          if [ "$AGENT_SUCCESS" == "true" ]; then
            echo "✅ **Status:** Completed successfully" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            echo "### Output" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            printf '%s\n' "$AGENT_OUTPUT" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
          else
            echo "❌ **Status:** Failed" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            echo "### Error" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            printf '%s\n' "$AGENT_ERROR" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
          fi

      - name: Fail if agent failed
        if: steps.run.outputs.success != 'true'
        run: exit 1

      - name: Update Check Run
        if: always()
        uses: actions/github-script@v8
        env:
          AGENT_OUTPUT: ${{ steps.run.outputs.output }}
          AGENT_ERROR: ${{ steps.run.outputs.error }}
          AGENT_SUCCESS: ${{ steps.run.outputs.success }}
          CHECK_RUN_ID: ${{ steps.check.outputs.id }}
        with:
          script: |
            const success = process.env.AGENT_SUCCESS === 'true';
            const output = process.env.AGENT_OUTPUT || '';
            const error = process.env.AGENT_ERROR || '';

            await github.rest.checks.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              check_run_id: parseInt(process.env.CHECK_RUN_ID, 10),
              status: 'completed',
              conclusion: success ? 'success' : 'failure',
              completed_at: new Date().toISOString(),
              output: {
                title: success ? 'Agent completed' : 'Agent failed',
                summary: success
                  ? `Agent completed successfully.\n\n<details><summary>Output</summary>\n\n\`\`\`\n${output.slice(0, 60000)}\n\`\`\`\n</details>`
                  : `Agent failed.\n\n\`\`\`\n${error.slice(0, 60000)}\n\`\`\``,
              },
            });
delete-stale-branches perms .github/workflows/delete-stale-branches.yaml
Triggers
schedule, workflow_dispatch
Runs on
ubuntu-latest
Jobs
stale_branches
Actions
crs-k/stale-branches
View raw YAML
name: Delete Stale Branches

on:
  schedule:
    - cron: "0 6 * * 1-5"
  workflow_dispatch:

permissions:
  issues: write
  contents: write

jobs:
  stale_branches:
    runs-on: ubuntu-latest
    steps:
      - name: Stale Branches
        uses: crs-k/stale-branches@v8.2.2
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"
          days-before-stale: 59
          days-before-delete: 60
          pr-check: true
          ignore-issue-interaction: true
          branches-filter-regex: "^(?!cla-signatures$).*"
jetbrains-release matrix .github/workflows/jetbrains-release.yaml
Triggers
release, workflow_dispatch
Runs on
ubuntu-latest, macos-latest, ${{ matrix.os }}, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
check_release_name, build, test-binaries, test, inspectCode, verify, upload-release
Matrix
include, include.arch, include.npm_config_arch, include.os, include.platform→ arm64, darwin, linux, macos-12, macos-latest, ubuntu-latest, win32, windows-latest, x64
Actions
apple-actions/import-codesign-certs, gradle/actions/wrapper-validation, gradle/actions/setup-gradle, gradle/actions/setup-gradle, jlumbroso/free-disk-space, JetBrains/qodana-action, jlumbroso/free-disk-space, gradle/actions/setup-gradle
Commands
  • if [[ "${{ github.event.release.tag_name }}" == v1.0.*-jetbrains ]]; then echo "should_run=true" >> $GITHUB_OUTPUT else echo "should_run=false" >> $GITHUB_OUTPUT fi
  • PROPERTIES="$(./gradlew properties --console=plain -q)" VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')" # CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)" CHANGELOG="" echo "version=$VERSION" >> $GITHUB_OUTPUT echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT echo "changelog<<EOF" >> $GITHUB_OUTPUT echo "$CHANGELOG" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT ./gradlew printProductsReleases # prepare list of IDEs for Plugin Verifier
  • cd ../.. && node ./scripts/build-packages.js
  • cd ../../core npm ci
  • cd ../../gui npm ci npm run build
  • cd ../../extensions/vscode npm ci npm run prepackage
  • cd ../../binary npm ci
  • cd ../../binary npm run build
View raw YAML
# GitHub Actions Workflow created for handling the release process based on the draft release prepared with the Build workflow.
# Running the publishPlugin task requires all following secrets to be provided: PUBLISH_TOKEN, PRIVATE_KEY, PRIVATE_KEY_PASSWORD, CERTIFICATE_CHAIN.
# See https://plugins.jetbrains.com/docs/intellij/plugin-signing.html for more information.

name: JetBrains Release

on:
  release:
    types: [prereleased]
  workflow_dispatch:
    inputs:
      build_only:
        description: "If true, only build the extension for the given channels, don't publish"
        required: true
        default: "true"
      eap_channel:
        description: "If true, build/publish the extension to the EAP channel"
        required: true
        default: "true"
      stable_channel:
        description: "If true, build/publish the extension to the Stable channel"
        required: true
        default: "true"

defaults:
  run:
    working-directory: extensions/intellij

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  check_release_name:
    runs-on: ubuntu-latest
    outputs:
      should_run: ${{ steps.check.outputs.should_run }}
    steps:
      - id: check
        working-directory: .
        run: |
          if [[ "${{ github.event.release.tag_name }}" == v1.0.*-jetbrains ]]; then
            echo "should_run=true" >> $GITHUB_OUTPUT
          else
            echo "should_run=false" >> $GITHUB_OUTPUT
          fi

  # bump-version:
  #   runs-on: ubuntu-latest
  #   needs:
  #     - check_release_name
  #   if: github.event_name != 'workflow_dispatch' || github.event.inputs.eap_channel == 'true' || github.event.inputs.stable_channel == 'true'
  #   permissions:
  #     contents: write
  #     pull-requests: write
  #   steps:
  #     # 0. Setup git
  #     - name: Checkout
  #       uses: actions/checkout@v6

  #     - name: Set up Git
  #       run: |
  #         git config --local user.email "action@github.com"
  #         git config --local user.name "GitHub Action"

  #     - name: Create PR branch
  #       run: |
  #         BRANCH_NAME="chore/bump-jetbrains-version-$(date +%Y%m%d-%H%M%S)"
  #         git checkout -b $BRANCH_NAME
  #         echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV

  #     - name: Bump version in gradle.properties
  #       run: |
  #         awk '/pluginVersion=/{split($0,a,"="); split(a[2],b,"."); b[3]+=1; printf "%s=%s.%s.%s\n",a[1],b[1],b[2],b[3];next}1' gradle.properties > tmp && mv tmp gradle.properties
  #         rm -rf tmp
  #         NEW_VERSION=$(grep 'pluginVersion=' gradle.properties | cut -d'=' -f2)
  #         echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_ENV

  #     - name: Create Pull Request
  #       uses: peter-evans/create-pull-request@v7
  #       with:
  #         token: ${{ secrets.CI_GITHUB_TOKEN }}
  #         commit-message: "chore: bump jetbrains extension version to ${{ env.NEW_VERSION }}"
  #         title: "chore: bump jetbrains extension version to ${{ env.NEW_VERSION }}"
  #         body: |
  #           Automated PR to bump the JetBrains extension version after successful pre-release publication.

  #           - Bumped version in extensions/intellij/gradle.properties to ${{ env.NEW_VERSION }}
  #         branch: ${{ env.BRANCH_NAME }}
  #         base: main
  #         delete-branch: true

  # Prepare and publish the plugin to JetBrains Marketplace repository
  build:
    needs: check_release_name
    if: needs.check_release_name.outputs.should_run == 'true' || github.event_name == 'workflow_dispatch'
    name: Build Plugin
    runs-on: macos-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      # Check out current repository
      - name: Fetch Sources
        uses: actions/checkout@v6
        with:
          ref: ${{ github.event.release.tag_name }}

      - name: Import Apple certificate
        uses: apple-actions/import-codesign-certs@v6
        with:
          keychain: ${{ github.run_id }}
          keychain-password: ${{ github.run_id }}
          p12-file-base64: ${{ secrets.APPLE_CERT_DATA }}
          p12-password: ${{ secrets.APPLE_CERT_PASSWORD }}

      # Validate wrapper
      - name: Gradle Wrapper Validation
        uses: gradle/actions/wrapper-validation@v6

      # # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v5
        with:
          distribution: zulu
          java-version: 17

      # # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v6
        with:
          gradle-home-cache-cleanup: true

      # Set environment variables
      - name: Export Properties
        id: properties
        shell: bash
        run: |
          PROPERTIES="$(./gradlew properties --console=plain -q)"
          VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
          # CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)"
          CHANGELOG=""

          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT

          echo "changelog<<EOF" >> $GITHUB_OUTPUT
          echo "$CHANGELOG" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

          ./gradlew printProductsReleases # prepare list of IDEs for Plugin Verifier

      # # Setup Node.js
      - name: Use Node.js from .nvmrc
        uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - name: Cache core node_modules
        uses: actions/cache@v5
        with:
          path: core/node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('core/package-lock.json') }}

      - name: Cache binary node_modules
        uses: actions/cache@v5
        with:
          path: binary/node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('binary/package-lock.json') }}

      - name: Cache gui node_modules
        uses: actions/cache@v5
        with:
          path: gui/node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('gui/package-lock.json') }}

      - name: Build packages (Unix)
        run: cd ../.. && node ./scripts/build-packages.js

      # npm install core
      - name: Install core node_modules
        run: |
          cd ../../core
          npm ci

      # npm install gui
      - name: Install gui node_modules and build
        run: |
          cd ../../gui
          npm ci
          npm run build
        env:
          NODE_OPTIONS: "--max-old-space-size=8192"

      # Run prepackage.js script
      - name: Run prepackage script
        run: |
          cd ../../extensions/vscode
          npm ci
          npm run prepackage
        env:
          # https://github.com/microsoft/vscode-ripgrep/issues/9#issuecomment-643965333
          GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }}

      # npm install binary
      - name: Install binary node_modules
        run: |
          cd ../../binary
          npm ci

      # Build binaries
      - name: Build the binaries
        run: |
          cd ../../binary
          npm run build

      # - name: Code sign darwin binaries
      #   run: |
      #     echo "Signing executable with keychain: ${{ github.run_id }}"
      #     codesign --sign - ../../binary/bin/darwin-x64/continue-binary
      #     codesign --sign - ../../binary/bin/darwin-arm64/continue-binary

      # - name: Sign darwin-arm64 binary
      #   uses: lando/code-sign-action@v2
      #   with:
      #     file: ./binary/bin/darwin-arm64/continue-binary
      #     certificate-data: ${{ secrets.APPLE_CERT_DATA }}
      #     certificate-password: ${{ secrets.APPLE_CERT_PASSWORD }}
      #     apple-notary-user: ${{ secrets.APPLE_NOTARY_USER }}
      #     apple-notary-password: ${{ secrets.APPLE_NOTARY_PASSWORD }}
      #     apple-notary-tool: altool
      #     apple-team-id: 43XFLY66ZD
      #     apple-product-id: dev.continue.continue-binary
      #     options: --options runtime --entitlements entitlements.xml

      # Build the plugin if not publishing
      - name: Build EAP Plugin (no publish)
        if: github.event_name != 'release' && github.event.inputs.eap_channel == 'true' && github.event.inputs.build_only == 'true'
        env:
          PUBLISH_TOKEN: ${{ secrets.JETBRAINS_PUBLISH_TOKEN }}
          CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
          PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
          PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}
          RELEASE_CHANNEL: eap
        run: ./gradlew buildPlugin --info --stacktrace

      - name: Build Stable Plugin (no publish)
        if: github.event_name != 'release' && github.event.inputs.stable_channel == 'true' && github.event.inputs.build_only == 'true'
        env:
          PUBLISH_TOKEN: ${{ secrets.JETBRAINS_PUBLISH_TOKEN }}
          CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
          PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
          PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}
          RELEASE_CHANNEL: default
        run: ./gradlew buildPlugin --info --stacktrace

      # Publish the plugin to JetBrains Marketplace
      - name: Publish EAP Plugin
        if: github.event_name == 'release' || (github.event.inputs.eap_channel == 'true' && github.event.inputs.build_only != 'true')
        continue-on-error: true
        env:
          PUBLISH_TOKEN: ${{ secrets.JETBRAINS_PUBLISH_TOKEN }}
          CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
          PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
          PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}
          RELEASE_CHANNEL: eap
        run: ./gradlew publishPlugin --info --stacktrace

      - name: Publish Stable Plugin
        if: github.event_name == 'release' || (github.event.inputs.stable_channel == 'true' && github.event.inputs.build_only != 'true')
        continue-on-error: true
        env:
          PUBLISH_TOKEN: ${{ secrets.JETBRAINS_PUBLISH_TOKEN }}
          CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
          PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
          PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}
          RELEASE_CHANNEL: default
        run: ./gradlew publishPlugin --info --stacktrace

      # Prepare plugin archive content for creating artifact
      - name: Prepare Plugin Artifact
        id: artifact
        shell: bash
        run: |
          cd ../../extensions/intellij/build/distributions
          echo "Contents of distributions folder:"
          ls
          echo "---"
          FILENAME=$(ls continue-intellij-extension-*.zip | head -1)
          echo "Filename=${FILENAME}"
          unzip "$FILENAME" -d content

          echo "filename=${FILENAME%.????}" >> $GITHUB_OUTPUT

      # Store already-built plugin as an artifact for downloading
      - name: Upload artifact
        uses: actions/upload-artifact@v7
        with:
          name: ${{ steps.artifact.outputs.filename }}
          path: ./extensions/intellij/build/distributions/content/*/*

      # Upload binaries as artifacts
      - name: Upload artifact (darwin-arm64)
        uses: actions/upload-artifact@v7
        with:
          name: continue-binary-darwin-arm64
          path: ./binary/bin/darwin-arm64/

      - name: Upload artifact (darwin-x64)
        uses: actions/upload-artifact@v7
        with:
          name: continue-binary-darwin-x64
          path: ./binary/bin/darwin-x64/

      - name: Upload artifact (win32-x64)
        uses: actions/upload-artifact@v7
        with:
          name: continue-binary-win32-x64
          path: ./binary/bin/win32-x64/

      - name: Upload artifact (win32-arm64)
        uses: actions/upload-artifact@v7
        with:
          name: continue-binary-win32-arm64
          path: ./binary/bin/win32-arm64/

      - name: Upload artifact (linux-arm64)
        uses: actions/upload-artifact@v7
        with:
          name: continue-binary-linux-arm64
          path: ./binary/bin/linux-arm64/

      - name: Upload artifact (linux-x64)
        uses: actions/upload-artifact@v7
        with:
          name: continue-binary-linux-x64
          path: ./binary/bin/linux-x64/

  test-binaries:
    needs: build
    strategy:
      matrix:
        include:
          - os: windows-latest
            platform: win32
            arch: x64
            npm_config_arch: x64
          - os: ubuntu-latest
            platform: linux
            arch: x64
            npm_config_arch: x64
          # arm64 not actually supported by GitHub
          # - os: ubuntu-latest
          #   platform: linux
          #   arch: arm64
          #   npm_config_arch: arm64
          - os: macos-12
            platform: darwin
            arch: x64
            npm_config_arch: x64
          - os: macos-latest
            platform: darwin
            arch: arm64
            npm_config_arch: arm64
    runs-on: ${{ matrix.os }}
    steps:
      # 1. Check-out repository
      - name: Check-out repository
        uses: actions/checkout@v6

      # 2. Install npm dependencies
      - name: Use Node.js from .nvmrc
        uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - name: Cache core node_modules
        uses: actions/cache@v5
        with:
          path: core/node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('core/package-lock.json') }}

      - name: Cache binary node_modules
        uses: actions/cache@v5
        with:
          path: binary/node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('binary/package-lock.json') }}

      - name: Install Core Dependencies
        run: |
          cd ../../core
          npm ci

      - name: Install Binary Dependencies
        run: |
          cd ../../binary
          npm ci

      # Download the binary artifact
      - name: Download binary artifact
        uses: actions/download-artifact@v8
        with:
          name: continue-binary-${{ matrix.platform }}-${{ matrix.arch }}
          path: ./binary/bin/${{ matrix.platform }}-${{ matrix.arch }}/

      # Set execute permissions for the binary (non-Windows)
      - name: Set execute permissions
        run: |
          cd ../../binary/bin/${{ matrix.platform }}-${{ matrix.arch }}
          chmod +x continue-binary
          chmod +x build/Release/node_sqlite3.node
          chmod +x index.node
        if: ${{ matrix.platform }} != 'win32'

      # Run tests for binary
      - name: Run binary tests
        run: |
          cd ../../binary
          npm run test

      - name: Upload logs
        if: ${{ always() }}
        uses: actions/upload-artifact@v7
        with:
          name: core-logs-${{ matrix.platform }}-${{ matrix.arch }}
          path: ~/.continue/logs/core.log

  # Run tests and upload a code coverage report
  test:
    name: Test
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      # Check out current repository
      - name: Fetch Sources
        uses: actions/checkout@v6

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v5
        with:
          distribution: zulu
          java-version: 17

      # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v6
        with:
          gradle-home-cache-cleanup: true

      # Run tests
      - name: Run Tests
        run: ./gradlew check

      # Collect Tests Result of failed tests
      - name: Collect Tests Result
        if: ${{ failure() }}
        uses: actions/upload-artifact@v7
        with:
          name: tests-result
          path: ${{ github.workspace }}/extensions/intellij/build/reports/tests

  # Run Qodana inspections and provide report
  inspectCode:
    if: false
    name: Inspect code
    needs: [build]
    runs-on: ubuntu-latest
    permissions:
      contents: write
      checks: write
      pull-requests: write
    steps:
      # Free GitHub Actions Environment Disk Space
      - name: Maximize Build Space
        uses: jlumbroso/free-disk-space@main
        with:
          tool-cache: false
          large-packages: false

      # Check out current repository
      - name: Fetch Sources
        uses: actions/checkout@v6

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v5
        with:
          distribution: zulu
          java-version: 17

      # Run Qodana inspections
      - name: Qodana - Code Inspection
        uses: JetBrains/qodana-action@v2025.3.2
        with:
          cache-default-branch-only: true

  # Run plugin structure verification along with IntelliJ Plugin Verifier
  verify:
    if: false
    name: Verify plugin
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      # Free GitHub Actions Environment Disk Space
      - name: Maximize Build Space
        uses: jlumbroso/free-disk-space@main
        with:
          tool-cache: false
          large-packages: false

      # Check out current repository
      - name: Fetch Sources
        uses: actions/checkout@v6

      # Set up Java environment for the next steps
      - name: Setup Java
        uses: actions/setup-java@v5
        with:
          distribution: zulu
          java-version: 17

      # Setup Gradle
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v6
        with:
          gradle-home-cache-cleanup: true

      # Cache Plugin Verifier IDEs
      - name: Setup Plugin Verifier IDEs Cache
        uses: actions/cache@v5
        with:
          path: ${{ needs.build.outputs.pluginVerifierHomeDir }}/ides
          key: plugin-verifier-${{ hashFiles('build/printProductsReleases.txt') }}

      # Run Verify Plugin task and IntelliJ Plugin Verifier tool
      - name: Run Plugin Verification tasks
        run: ./gradlew runPluginVerifier -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }}

      # Collect Plugin Verifier Result
      - name: Collect Plugin Verifier Result
        if: ${{ always() }}
        uses: actions/upload-artifact@v7
        with:
          name: pluginVerifier-result
          path: ${{ github.workspace }}/build/reports/pluginVerifier

  upload-release:
    if: false
    name: Upload Release
    needs:
      - build
      - test-binaries
      - test
    runs-on: ubuntu-latest
    steps:
      # # Update Unreleased section with the current release note
      # - name: Patch Changelog
      #   if: ${{ steps.properties.outputs.changelog != '' }}
      #   env:
      #     CHANGELOG: ${{ steps.properties.outputs.changelog }}
      #   run: |
      #     ./gradlew patchChangelog --release-note="$CHANGELOG"

      - name: Download the plugin
        uses: actions/download-artifact@v8
        with:
          name: ${{ steps.artifact.outputs.filename }}
          path: ./build/distributions/

      # Upload artifact as a release asset
      # - name: Upload Release Asset
      #   env:
      #     GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      #   run: gh release upload ${{ github.event.release.tag_name }} ./build/distributions/*

      # Publish the plugin to JetBrains Marketplace
      - name: Publish Plugin
        env:
          PUBLISH_TOKEN: ${{ secrets.JETBRAINS_PUBLISH_TOKEN }}
          CERTIFICATE_CHAIN: ${{ secrets.JETBRAINS_CERTIFICATE_CHAIN }}
          PRIVATE_KEY: ${{ secrets.JETBRAINS_PRIVATE_KEY }}
          PRIVATE_KEY_PASSWORD: ${{ secrets.JETBRAINS_PRIVATE_KEY_PASSWORD }}
        run: ./gradlew publishPlugin

      # Create a pull request
      - name: Create Pull Request
        if: ${{ steps.properties.outputs.changelog != '' }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          VERSION="${{ github.event.release.tag_name }}"
          BRANCH="changelog-update-$VERSION"
          LABEL="release changelog"

          git config user.email "action@github.com"
          git config user.name "GitHub Action"

          git checkout -b $BRANCH
          git commit -am "Changelog update - $VERSION"
          git push --set-upstream origin $BRANCH

          gh label create "$LABEL" \
            --description "Pull requests with release changelog update" \
            --force \
            || true

          gh pr create \
            --title "Changelog update - \`$VERSION\`" \
            --body "Current pull request contains patched \`CHANGELOG.md\` file for the \`$VERSION\` version." \
            --label "$LABEL" \
            --head $BRANCH
label-merged-prs .github/workflows/label-merged-prs.yml
Triggers
pull_request
Runs on
ubuntu-latest
Jobs
label-pr
Commands
  • USERS=( "TyDunn" "jpoly1219" "bdougie" "uinstinct" "sestinj" "tingwai" "tomasz-stefaniak" "RomneyDa" "Patrick-Erichsen" ) PR_AUTHOR="${{ github.event.pull_request.user.login }}" SHOULD_LABEL="false" for user in "${USERS[@]}"; do if [[ "$PR_AUTHOR" == "$user" ]]; then SHOULD_LABEL="true" break fi done echo "should_label=$SHOULD_LABEL" >> $GITHUB_OUTPUT
View raw YAML
name: Label Merged PRs

on:
  pull_request:
    types: [closed]

jobs:
  label-pr:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
      
      - name: Check if author is in tier list
        id: check-author
        run: |
          USERS=(
            "TyDunn"
            "jpoly1219"
            "bdougie"
            "uinstinct"
            "sestinj"
            "tingwai"
            "tomasz-stefaniak"
            "RomneyDa"
            "Patrick-Erichsen"
          )
          
          PR_AUTHOR="${{ github.event.pull_request.user.login }}"
          SHOULD_LABEL="false"
          
          for user in "${USERS[@]}"; do
            if [[ "$PR_AUTHOR" == "$user" ]]; then
              SHOULD_LABEL="true"
              break
            fi
          done
          
          echo "should_label=$SHOULD_LABEL" >> $GITHUB_OUTPUT
      
      - name: Determine and apply tier label
        if: steps.check-author.outputs.should_label == 'true'
        uses: actions/github-script@v8
        with:
          script: |
            const pr = context.payload.pull_request;
            
            // Check if PR already has a tier label
            const existingLabels = pr.labels.map(l => l.name);
            if (existingLabels.some(label => label.match(/^tier [1-3]$/))) {
              console.log('PR already has a tier label, skipping');
              return;
            }
            
            // Function to extract conventional commit prefix
            function getConventionalPrefix(title) {
              const match = title.match(/^([a-z]+)(\s|$|:)/);
              return match ? match[1] : '';
            }
            
            // Function to determine tier
            function determineTier(pr) {
              const additions = pr.additions;
              const deletions = pr.deletions;
              const changedFiles = pr.changed_files;
              const title = pr.title;
              const body = pr.body || '';
              
              const prefix = getConventionalPrefix(title);
              
              // If no conventional commit prefix, skip
              if (!prefix) {
                console.log('No conventional commit format, skipping');
                return null;
              }
              
              // Tier 4 (unlabeled): fix, test, docs, style, refactor, perf, build, ci, revert, improve
              const tier4Prefixes = ['fix', 'test', 'docs', 'style', 'refactor', 'perf', 'build', 'ci', 'revert', 'chore', 'improve'];
              if (tier4Prefixes.includes(prefix)) {
                console.log('Tier 4 prefix detected, will remain unlabeled');
                return null;
              }
              
              const totalChanges = additions + deletions;
              
              // Tier 1: Major features (1000+ lines changed, or 20+ files, or feat with large scope)
              if (totalChanges > 1000 || changedFiles > 20 || 
                  (prefix === 'feat' && totalChanges > 800) ||
                  title.match(/(major|milestone|launch)/)) {
                return 'tier 1';
              }
              
              // Tier 2: Important features (500+ lines changed, or 10+ files, or standard feat)
              if (totalChanges > 500 || changedFiles > 10 || prefix === 'feat') {
                return 'tier 2';
              }
              
              // Tier 3: Smaller improvements
              return 'tier 3';
            }
            
            const tier = determineTier(pr);
            
            if (tier) {
              console.log(`Assigning ${tier} label to PR #${pr.number}`);
              console.log(`Title: ${pr.title}`);
              console.log(`Changes: +${pr.additions} -${pr.deletions} (${pr.changed_files} files)`);
              
              await github.rest.issues.addLabels({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: pr.number,
                labels: [tier]
              });
              
              console.log(`✓ Label '${tier}' added successfully`);
            }
main matrix .github/workflows/main.yaml
Triggers
release, workflow_dispatch
Runs on
ubuntu-latest, ubuntu-latest, ${{ matrix.os }}, ubuntu-latest, ubuntu-latest
Jobs
check_release_name, check-version, build, release, publish
Matrix
include, include.arch, include.npm_config_arch, include.os, include.platform→ alpine, arm, arm64, armhf, darwin, linux, macos-latest, ubuntu-latest, win32, windows-latest, x64
Actions
softprops/action-gh-release
Commands
  • if [[ "${{ github.event.release.tag_name }}" == v1.2.*-vscode ]]; then echo "should_run=true" >> $GITHUB_OUTPUT else echo "should_run=false" >> $GITHUB_OUTPUT fi
  • git checkout ${GITHUB_REF#refs/tags/}
  • cd extensions/vscode node scripts/versionCheck.js
  • git config --local user.email "action@github.com" git config --local user.name "GitHub Action"
  • git config --local user.email "action@github.com" git config --local user.name "GitHub Action"
  • git fetch origin ${{ github.ref }} && git checkout ${{ github.ref }}
  • cd extensions/vscode npx @vscode/vsce publish --packagePath ../../vsix-artifacts/*.vsix
  • cd extensions/vscode npx ovsx publish -p ${{ secrets.VSX_REGISTRY_TOKEN }} --packagePath ../../vsix-artifacts/*.vsix
View raw YAML
name: Publish Extension

on:
  release:
    types: [released]

  workflow_dispatch:
    inputs:
      publish_build:
        description: "Whether or not to publish the built extension to the VS Code marketplace"
        required: true
        default: "false"

jobs:
  check_release_name:
    runs-on: ubuntu-latest
    outputs:
      should_run: ${{ steps.check.outputs.should_run }}
    steps:
      - id: check
        working-directory: .
        run: |
          if [[ "${{ github.event.release.tag_name }}" == v1.2.*-vscode ]]; then
            echo "should_run=true" >> $GITHUB_OUTPUT
          else
            echo "should_run=false" >> $GITHUB_OUTPUT
          fi

  check-version:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6
        with:
          fetch-depth: 0 # This ensures all tags are fetched

      - name: Checkout tag
        run: git checkout ${GITHUB_REF#refs/tags/}

      - name: Make sure version isn't odd
        run: |
          cd extensions/vscode
          node scripts/versionCheck.js

  build:
    needs: [check_release_name, check-version]
    if: needs.check_release_name.outputs.should_run == 'true' || github.event_name == 'workflow_dispatch'
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: windows-latest
            platform: win32
            arch: x64
            npm_config_arch: x64
          - os: windows-latest
            platform: win32
            arch: arm64
            npm_config_arch: arm
          - os: ubuntu-latest
            platform: linux
            arch: x64
            npm_config_arch: x64
          - os: ubuntu-latest
            platform: linux
            arch: arm64
            npm_config_arch: arm64
          - os: ubuntu-latest
            platform: linux
            arch: armhf
            npm_config_arch: arm
          - os: ubuntu-latest
            platform: alpine
            arch: x64
            npm_config_arch: x64
          - os: macos-latest
            platform: darwin
            arch: x64
            npm_config_arch: x64
          - os: macos-latest
            platform: darwin
            arch: arm64
            npm_config_arch: arm64
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - uses: ./.github/actions/build-vscode-extension
        with:
          platform: ${{ matrix.platform }}
          arch: ${{ matrix.arch }}
          npm_config_arch: ${{ matrix.npm_config_arch }}
          pre-release: false
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload .vsix artifact
        uses: actions/upload-artifact@v7
        with:
          name: ${{ matrix.platform }}-${{ matrix.arch }}-vsix
          path: "extensions/vscode/*.vsix"

  release:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    needs:
      - build
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Set up Git
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"

      # Download the .vsix artifacts
      - uses: actions/download-artifact@v8
        with:
          pattern: "*-vsix"
          path: vsix-artifacts
          merge-multiple: true

      - name: Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: ${{ github.ref_name }}
          files: |
            vsix-artifacts/*.vsix
          token: ${{ secrets.CI_GITHUB_TOKEN }}
          repository: continuedev/continue

  publish:
    runs-on: ubuntu-latest
    needs:
      - build
    if: github.event_name != 'workflow_dispatch' || github.event.inputs.publish_build == 'true'
    permissions:
      contents: write
    steps:
      # 0. Setup git
      - name: Checkout
        uses: actions/checkout@v6

      - name: Set up Git
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"

      - name: Pull latest changes from release
        run: git fetch origin ${{ github.ref }} && git checkout ${{ github.ref }}

      # 1. Download the artifacts
      - uses: actions/download-artifact@v8
        with:
          pattern: "*-vsix"
          path: vsix-artifacts
          merge-multiple: true

      # 2. Publish the extension to VS Code Marketplace
      - name: Publish to VS Code Marketplace
        run: |
          cd extensions/vscode
          npx @vscode/vsce publish --packagePath ../../vsix-artifacts/*.vsix
        env:
          VSCE_PAT: ${{ secrets.VSCE_TOKEN }}

      # 3. Publish the extension to Open VSX Registry
      - name: Publish (Open VSX Registry)
        continue-on-error: true
        run: |
          cd extensions/vscode
          npx ovsx publish -p ${{ secrets.VSX_REGISTRY_TOKEN }} --packagePath ../../vsix-artifacts/*.vsix
main-build matrix .github/workflows/main-build.yaml
Triggers
push, workflow_dispatch
Runs on
ubuntu-latest
Jobs
republish-pr-artifacts
Matrix
platform→ Linux, macOS
Commands
  • # Get PR number for the current commit using GitHub API COMMIT_SHA=$(git rev-parse HEAD) echo "Getting PR for commit: $COMMIT_SHA" PR_NUMBER=$(curl -s -H "Authorization: token $GH_TOKEN" \ "https://api.github.com/repos/${{ github.repository }}/commits/$COMMIT_SHA/pulls" \ | jq -r '.[0].number // empty') if [ -z "$PR_NUMBER" ]; then echo "❌ Could not find PR for commit $COMMIT_SHA" exit 1 fi echo "Found PR number: $PR_NUMBER" echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
  • echo "🔍 Getting branch name for PR #$PR_NUMBER..." # Get the branch name for the PR BRANCH_NAME=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName --jq '.headRefName') if [ -z "$BRANCH_NAME" ]; then echo "❌ Could not find PR #$PR_NUMBER" exit 1 fi echo "Branch name: $BRANCH_NAME" # Get the latest successful workflow run for the branch RUN_ID=$(gh run list \ --repo "${{ github.repository }}" \ --workflow="pr_checks.yaml" \ --branch="$BRANCH_NAME" \ --json databaseId,status,conclusion \ --jq ".[] | select(.status == \"completed\" and .conclusion == \"success\") | .databaseId" \ | head -1) if [ -z "$RUN_ID" ]; then echo "❌ No successful workflow run found for PR #$PR_NUMBER (branch: $BRANCH_NAME)" exit 1 fi echo "Found successful workflow run: $RUN_ID" echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
  • echo "📥 Downloading vscode-extension-build-$PLATFORM artifact from run $RUN_ID..." # Create temporary directory for download mkdir -p ./temp-download # Download the artifact from the PR workflow run if ! gh run download "$RUN_ID" \ --repo "${{ github.repository }}" \ --name "vscode-extension-build-$PLATFORM" \ --dir "./temp-download"; then echo "❌ Failed to download artifact vscode-extension-build-$PLATFORM from run $RUN_ID" exit 1 fi echo "✅ Successfully downloaded artifact"
View raw YAML
name: Main Branch Build

# Download and republish VS Code extension artifacts when code is merged to main
on:
  push:
    branches:
      - main
  workflow_dispatch:
    inputs:
      test_pr_number:
        description: "PR number to test with"
        required: true

jobs:
  republish-pr-artifacts:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        platform: [Linux, macOS]
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 2 # Get the last 2 commits to find the merge commit

      - name: Get merged PR number
        id: get-pr
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Get PR number for the current commit using GitHub API
          COMMIT_SHA=$(git rev-parse HEAD)
          echo "Getting PR for commit: $COMMIT_SHA"

          PR_NUMBER=$(curl -s -H "Authorization: token $GH_TOKEN" \
            "https://api.github.com/repos/${{ github.repository }}/commits/$COMMIT_SHA/pulls" \
            | jq -r '.[0].number // empty')

          if [ -z "$PR_NUMBER" ]; then
            echo "❌ Could not find PR for commit $COMMIT_SHA"
            exit 1
          fi

          echo "Found PR number: $PR_NUMBER"
          echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT

      - name: Find PR workflow run
        id: find-run
        env:
          PR_NUMBER: ${{ steps.get-pr.outputs.pr_number }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "🔍 Getting branch name for PR #$PR_NUMBER..."

          # Get the branch name for the PR
          BRANCH_NAME=$(gh pr view "$PR_NUMBER" --repo "${{ github.repository }}" --json headRefName --jq '.headRefName')

          if [ -z "$BRANCH_NAME" ]; then
            echo "❌ Could not find PR #$PR_NUMBER"
            exit 1
          fi

          echo "Branch name: $BRANCH_NAME"

          # Get the latest successful workflow run for the branch
          RUN_ID=$(gh run list \
            --repo "${{ github.repository }}" \
            --workflow="pr_checks.yaml" \
            --branch="$BRANCH_NAME" \
            --json databaseId,status,conclusion \
            --jq ".[] | select(.status == \"completed\" and .conclusion == \"success\") | .databaseId" \
            | head -1)

          if [ -z "$RUN_ID" ]; then
            echo "❌ No successful workflow run found for PR #$PR_NUMBER (branch: $BRANCH_NAME)"
            exit 1
          fi

          echo "Found successful workflow run: $RUN_ID"
          echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT

      - name: Download PR artifact
        env:
          RUN_ID: ${{ steps.find-run.outputs.run_id }}
          PLATFORM: ${{ matrix.platform }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "📥 Downloading vscode-extension-build-$PLATFORM artifact from run $RUN_ID..."

          # Create temporary directory for download
          mkdir -p ./temp-download

          # Download the artifact from the PR workflow run
          if ! gh run download "$RUN_ID" \
            --repo "${{ github.repository }}" \
            --name "vscode-extension-build-$PLATFORM" \
            --dir "./temp-download"; then
            echo "❌ Failed to download artifact vscode-extension-build-$PLATFORM from run $RUN_ID"
            exit 1
          fi

          echo "✅ Successfully downloaded artifact"

      - name: Republish as main branch artifact
        uses: actions/upload-artifact@v7
        with:
          name: vscode-extension-build-${{ matrix.platform }}
          path: ./temp-download/*
metrics perms .github/workflows/metrics.yaml
Triggers
workflow_dispatch, schedule, push
Runs on
ubuntu-latest
Jobs
build
Actions
github/issue-metrics, slackapi/slack-github-action
Commands
  • # Calculate the first day of the previous month first_day=$(date -d "last month" +%Y-%m-01) # Calculate the last day of the previous month last_day=$(date -d "$first_day +1 month -1 day" +%Y-%m-%d) #Set an environment variable with the date range echo "$first_day..$last_day" echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"
  • content=$(cat ./issue_metrics.md) # This prepares the content in a way that can be used in GitHub Actions content="${content//'%'/'%25'}" content="${content//$'\n'/'%0A'}" # content="${content//$'\r'/'%0D'}" echo "metrics_content=$content" >> "$GITHUB_OUTPUT"
View raw YAML
name: Monthly issue metrics
on:
  workflow_dispatch:
  schedule:
    # Runs every Monday at 9:00 AM PST (17:00 UTC)
    - cron: "0 17 * * 1"

  push:
    branches:
      - nate/metrics-action

permissions:
  contents: read

jobs:
  build:
    name: issue metrics
    runs-on: ubuntu-latest
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    permissions:
      issues: write
      pull-requests: read
    steps:
      - name: Get dates for last month
        shell: bash
        run: |
          # Calculate the first day of the previous month
          first_day=$(date -d "last month" +%Y-%m-01)

          # Calculate the last day of the previous month
          last_day=$(date -d "$first_day +1 month -1 day" +%Y-%m-%d)

          #Set an environment variable with the date range
          echo "$first_day..$last_day"
          echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV"

      - name: Run issue-metrics tool
        uses: github/issue-metrics@v3
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SEARCH_QUERY: 'repo:continuedev/continue created:${{ env.last_month }} -reason:"not planned"'

      - name: Read metrics file content
        id: read-metrics
        run: |
          content=$(cat ./issue_metrics.md)
          # This prepares the content in a way that can be used in GitHub Actions
          content="${content//'%'/'%25'}"
          content="${content//$'\n'/'%0A'}"
          # content="${content//$'\r'/'%0D'}"
          echo "metrics_content=$content" >> "$GITHUB_OUTPUT"

      - name: Post a message in a channel
        uses: slackapi/slack-github-action@v3.0.1
        with:
          webhook: ${{ secrets.ISSUE_PR_METRICS_SLACK_WEBHOOK_URL }}
          webhook-type: incoming-webhook
          payload: |
            text: "Issue / PR Metrics Report"
            blocks:
                - type: "header"
                  text:
                    type: "plain_text"
                    text: "Monthly Issue Metrics Report"
                    emoji: true
                - type: "section"
                  text:
                    type: "mrkdwn"
                    text: |
                      ${{ steps.read-metrics.outputs.metrics_content }}

      - name: Upload metrics report as artifact
        uses: actions/upload-artifact@v7
        with:
          name: issue-metrics-report
          path: ./issue_metrics.md
pr-build-upload-vsix matrix .github/workflows/pr-build-upload-vsix.yaml
Triggers
pull_request
Runs on
${{ matrix.runner }}
Jobs
build-and-upload-vsix
Matrix
include, include.arch, include.platform, include.runner→ arm64, darwin, linux, macos-latest, ubuntu-latest, win32, windows-latest, x64
View raw YAML
name: PR Build And Upload VSIX

# Builds and uploads VSIX artifacts for the `oneper` script across Linux, Windows, and macOS ARM platforms
on:
  pull_request:
    branches:
      - main

jobs:
  build-and-upload-vsix:
    runs-on: ${{ matrix.runner }}
    timeout-minutes: 10
    strategy:
      matrix:
        include:
          - platform: linux
            arch: x64
            runner: ubuntu-latest
          - platform: win32
            arch: x64
            runner: windows-latest
          - platform: darwin
            arch: arm64
            runner: macos-latest

    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Build VS Code extension
        uses: ./.github/actions/build-vscode-extension
        with:
          platform: ${{ matrix.platform }}
          arch: ${{ matrix.arch }}
          npm_config_arch: ${{ matrix.arch }}
          pre-release: false
          commit-sha: ${{ github.sha }}
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload build artifact
        uses: actions/upload-artifact@v7
        with:
          name: vscode-extension-build-${{ matrix.platform }}-${{ matrix.arch }}
          path: extensions/vscode/build

      - name: Upload .vsix artifact
        uses: actions/upload-artifact@v7
        with:
          name: ${{ matrix.platform }}-${{ matrix.arch }}-vsix
          path: "extensions/vscode/*.vsix"
pr-checks matrix .github/workflows/pr-checks.yaml
Triggers
pull_request, push
Runs on
ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
track-rerun, prettier-check, core-checks, gui-checks, binary-checks, vscode-checks, get-packages-matrix, packages-checks, vscode-get-test-file-matrix, vscode-package-extension-linux, vscode-e2e-tests, jetbrains-tests, require-all-checks-to-pass
Matrix
command, package, test_file→ ${{ fromJson(needs.get-packages-matrix.outputs.packages) }}, ${{ fromJson(needs.vscode-get-test-file-matrix.outputs.test_file_matrix) }}, e2e:ci:run, e2e:ci:run-yaml
Actions
jlumbroso/free-disk-space, re-actors/alls-green
Commands
  • npm ci
  • npx prettier --check "**/*.{js,jsx,ts,tsx,json,css,md}" --ignore-path .gitignore --ignore-path .prettierignore
  • cd core npx tsc --noEmit npm run lint
  • cd core npm test npm run vitest
  • cd gui npx tsc --noEmit npm run lint
  • cd gui npm test
  • cd binary npx tsc --noEmit
  • cd extensions/vscode npm run write-build-timestamp npx tsc --noEmit npm run lint
View raw YAML
name: PR Checks

# PR Checks run on all PRs to the main branch and must pass before merging.
on:
  pull_request:
    branches:
      - main

  push:
    branches:
      - main

jobs:
  track-rerun:
    runs-on: ubuntu-latest
    if: github.run_attempt > 1
    steps:
      - uses: actions/checkout@v6
      - name: Track workflow rerun
        uses: ./.github/actions/track-rerun

  prettier-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - uses: actions/cache@v5
        id: root-cache
        with:
          path: node_modules
          key: ${{ runner.os }}-root-node-modules-${{ hashFiles('package-lock.json') }}

      - name: Install root dependencies
        if: steps.root-cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: Check code formatting with Prettier
        run: npx prettier --check "**/*.{js,jsx,ts,tsx,json,css,md}" --ignore-path .gitignore --ignore-path .prettierignore

  core-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0 # Needed for git diff to work
      - name: Setup packages
        uses: ./.github/actions/setup-packages
      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true

      - name: Check if LLM-related files changed
        id: llm-changes
        uses: ./.github/actions/check-llm-changes
        with:
          is_fork: ${{ github.event.pull_request.head.repo.fork == true }}
          is_dependabot: ${{ github.actor == 'dependabot[bot]' }}

      - name: Type check and lint
        run: |
          cd core
          npx tsc --noEmit
          npm run lint
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

      - name: Run tests
        run: |
          cd core
          npm test
          npm run vitest
        env:
          IGNORE_API_KEY_TESTS: ${{ steps.llm-changes.outputs.ignore_api_tests }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
          MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
          AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
          AZURE_FOUNDRY_CODESTRAL_API_KEY: ${{ secrets.AZURE_FOUNDRY_CODESTRAL_API_KEY }}
          AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY: ${{ secrets.AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY }}
          AZURE_OPENAI_GPT41_API_KEY: ${{ secrets.AZURE_OPENAI_GPT41_API_KEY }}
          VOYAGE_API_KEY: ${{ secrets.VOYAGE_API_KEY }}
          RELACE_API_KEY: ${{ secrets.RELACE_API_KEY }}
          INCEPTION_API_KEY: ${{ secrets.INCEPTION_API_KEY }}

  gui-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Setup packages
        uses: ./.github/actions/setup-packages
      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true
      - name: Setup gui component
        uses: ./.github/actions/setup-component
        with:
          component: gui
          include-packages: false
        env:
          GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }}

      - name: Type check and lint
        run: |
          cd gui
          npx tsc --noEmit
          npm run lint

      - name: Run tests
        run: |
          cd gui
          npm test

  binary-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Setup packages
        uses: ./.github/actions/setup-packages
      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true
      - name: Setup binary component
        uses: ./.github/actions/setup-component
        with:
          component: binary
          include-packages: false

      - name: Type check
        run: |
          cd binary
          npx tsc --noEmit

  vscode-checks:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Setup packages
        uses: ./.github/actions/setup-packages
      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true
      - name: Setup vscode component
        uses: ./.github/actions/setup-component
        with:
          component: vscode
          include-packages: false
        env:
          GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }}

      - name: Type check and lint
        run: |
          cd extensions/vscode
          npm run write-build-timestamp
          npx tsc --noEmit
          npm run lint

      - name: Run vitest tests
        run: |
          cd extensions/vscode
          npm run vitest

  get-packages-matrix:
    runs-on: ubuntu-latest
    outputs:
      packages: ${{ steps.get-packages.outputs.packages }}
    steps:
      - uses: actions/checkout@v6
      - name: Get package list
        id: get-packages
        run: |
          packages=$(find packages/ -maxdepth 1 -type d -not -path packages/ -exec basename {} \; | sort | jq -R -s -c 'split("\n")[:-1]')
          echo "packages=$packages" >> $GITHUB_OUTPUT
          echo "Found packages: $packages"

  packages-checks:
    needs: get-packages-matrix
    runs-on: ubuntu-latest
    strategy:
      matrix:
        package: ${{ fromJson(needs.get-packages-matrix.outputs.packages) }}
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0 # Needed for git diff to work
      - name: Setup packages
        uses: ./.github/actions/setup-packages

      - name: Check if LLM-related files changed
        id: llm-changes
        uses: ./.github/actions/check-llm-changes
        with:
          is_fork: ${{ github.event.pull_request.head.repo.fork == true }}
          is_dependabot: ${{ github.actor == 'dependabot[bot]' }}

      - name: Test and check ${{ matrix.package }}
        run: |
          cd packages/${{ matrix.package }}
          npm ci
          npm test
        env:
          IGNORE_API_KEY_TESTS: ${{ steps.llm-changes.outputs.ignore_api_tests }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
          MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
          AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
          AZURE_FOUNDRY_CODESTRAL_API_KEY: ${{ secrets.AZURE_FOUNDRY_CODESTRAL_API_KEY }}
          AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY: ${{ secrets.AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY }}
          AZURE_OPENAI_GPT41_API_KEY: ${{ secrets.AZURE_OPENAI_GPT41_API_KEY }}
          VOYAGE_API_KEY: ${{ secrets.VOYAGE_API_KEY }}
          RELACE_API_KEY: ${{ secrets.RELACE_API_KEY }}
          INCEPTION_API_KEY: ${{ secrets.INCEPTION_API_KEY }}

  vscode-get-test-file-matrix:
    runs-on: ubuntu-latest
    outputs:
      test_file_matrix: ${{ steps.vscode-get-test-file-matrix.outputs.test_file_matrix }}
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - name: Cache npm
        uses: actions/cache@v5
        with:
          path: ~/.npm
          key: ${{ runner.os }}-npm-cache-matrix-${{ hashFiles('core/package-lock.json', 'extensions/vscode/package-lock.json') }}

      - name: Cache packages node_modules
        uses: actions/cache@v5
        with:
          path: |
            packages/*/node_modules
          key: ${{ runner.os }}-packages-node-modules-${{ hashFiles('packages/*/package-lock.json') }}

      - name: Cache core node modules
        uses: actions/cache@v5
        with:
          path: core/node_modules
          key: ${{ runner.os }}-core-node-modules-${{ hashFiles('core/package-lock.json') }}

      - name: Cache vscode extension node modules
        uses: actions/cache@v5
        id: vscode-cache
        with:
          path: extensions/vscode/node_modules
          key: ${{ runner.os }}-vscode-node-modules-${{ hashFiles('extensions/vscode/package-lock.json') }}

      - name: Build packages and get test files
        id: vscode-get-test-file-matrix
        run: |
          node ./scripts/build-packages.js
          cd extensions/vscode
          npm ci
          npm run e2e:compile
          if [[ "${{ github.event.pull_request.head.repo.fork }}" == "true" || "${{ github.actor }}" == "dependabot[bot]" ]]; then
            # Exclude SSH tests for forks
            FILES=$(ls -1 e2e/_output/tests/*.test.js | grep -v "SSH" | jq -R . | jq -s .)
          else
            # Include all tests for non-forks
            FILES=$(ls -1 e2e/_output/tests/*.test.js | jq -R . | jq -s .)
          fi
          echo "test_file_matrix<<EOF" >> $GITHUB_OUTPUT
          echo "$FILES" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
        env:
          # https://github.com/microsoft/vscode-ripgrep/issues/9#issuecomment-643965333
          GITHUB_TOKEN: ${{ secrets.CI_GITHUB_TOKEN }}

      - name: Debug Outputs
        run: |
          echo "Test files: ${{ steps.vscode-get-test-file-matrix.outputs.test_file_matrix }}"

  vscode-package-extension-linux:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Build VS Code extension
        uses: ./.github/actions/build-vscode-extension
        with:
          platform: linux
          arch: x64
          npm_config_arch: x64
          pre-release: false
          commit-sha: ${{ github.sha }}
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload build artifact
        uses: actions/upload-artifact@v7
        with:
          name: vscode-extension-build-Linux
          path: extensions/vscode/build

  vscode-e2e-tests:
    name: ${{ matrix.test_file || 'unknown' }} (${{ matrix.command }})
    needs: [vscode-get-test-file-matrix, vscode-package-extension-linux]
    runs-on: ubuntu-latest
    timeout-minutes: 15
    # Tests requiring secrets need approval from maintainers
    strategy:
      fail-fast: false
      matrix:
        test_file: ${{ fromJson(needs.vscode-get-test-file-matrix.outputs.test_file_matrix) }}
        command: ["e2e:ci:run", "e2e:ci:run-yaml"]
    steps:
      - uses: actions/checkout@v6
      - name: Run VS Code E2E test
        uses: ./.github/actions/run-vscode-e2e-test
        with:
          test_file: ${{ matrix.test_file }}
          command: ${{ matrix.command }}
          ssh_key: ${{ secrets.GH_ACTIONS_SSH_TEST_KEY_PEM }}
          ssh_host: ${{ secrets.GH_ACTIONS_SSH_TEST_DNS_NAME }}
          is_fork: ${{ github.event.pull_request.head.repo.fork == true || github.actor == 'dependabot[bot]' }}
          github_token: ${{ secrets.CI_GITHUB_TOKEN }}

  jetbrains-tests:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Free disk space
        uses: jlumbroso/free-disk-space@main
        with:
          tool-cache: false
          android: true
          dotnet: true
          haskell: true
          large-packages: false
          docker-images: true
          swap-storage: true

      - uses: actions/checkout@v6
      - name: Run JetBrains tests
        uses: ./.github/actions/run-jetbrains-tests
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          ci-github-token: ${{ secrets.CI_GITHUB_TOKEN }}

  # GitHub does not have a way of requiring that all checks pass (you must manually select each job)
  # This action at least lets us manage the list of required tests via source control

  # so that creators of new jobs can add them to this list
  require-all-checks-to-pass:
    if: always()
    runs-on: ubuntu-latest
    needs:
      - prettier-check
      - core-checks
      - gui-checks
      - binary-checks
      - vscode-checks
      - get-packages-matrix
      - packages-checks
      - vscode-get-test-file-matrix
      - vscode-package-extension-linux
      - vscode-e2e-tests
      - jetbrains-tests

    steps:
      - name: Decide whether the needed jobs succeeded or failed
        uses: re-actors/alls-green@release/v1
        with:
          jobs: ${{ toJSON(needs) }}
preview matrix .github/workflows/preview.yaml
Triggers
release, workflow_dispatch
Runs on
ubuntu-latest, ${{ matrix.os }}, ubuntu-latest, ubuntu-latest
Jobs
check_release_name, build, release, publish
Matrix
include, include.arch, include.npm_config_arch, include.os, include.platform→ alpine, arm, arm64, armhf, darwin, linux, macos-latest, ubuntu-latest, win32, windows-latest, x64
Actions
softprops/action-gh-release
Commands
  • if [[ "${{ github.event.release.tag_name }}" == v1.3.*-vscode ]]; then echo "should_run=true" >> $GITHUB_OUTPUT else echo "should_run=false" >> $GITHUB_OUTPUT fi
  • git config --local user.email "action@github.com" git config --local user.name "GitHub Action"
  • cd extensions/vscode npx @vscode/vsce publish --pre-release --packagePath ../../vsix-artifacts/*.vsix
  • cd extensions/vscode npx ovsx publish --pre-release -p ${{ secrets.VSX_REGISTRY_TOKEN }} --packagePath ../../vsix-artifacts/*.vsix
View raw YAML
name: Publish Pre-release Extension

on:
  release:
    types: [prereleased]

  workflow_dispatch:
    inputs:
      publish_build:
        description: "Whether or not to publish the built extension to the VS Code marketplace"
        required: true
        default: "false"

jobs:
  check_release_name:
    runs-on: ubuntu-latest
    outputs:
      should_run: ${{ steps.check.outputs.should_run }}
    steps:
      - id: check
        working-directory: .
        run: |
          if [[ "${{ github.event.release.tag_name }}" == v1.3.*-vscode ]]; then
            echo "should_run=true" >> $GITHUB_OUTPUT
          else
            echo "should_run=false" >> $GITHUB_OUTPUT
          fi

  build:
    needs: check_release_name
    if: needs.check_release_name.outputs.should_run == 'true' || github.event_name == 'workflow_dispatch'
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: windows-latest
            platform: win32
            arch: x64
            npm_config_arch: x64
          - os: windows-latest
            platform: win32
            arch: arm64
            npm_config_arch: arm
          - os: ubuntu-latest
            platform: linux
            arch: x64
            npm_config_arch: x64
          - os: ubuntu-latest
            platform: linux
            arch: arm64
            npm_config_arch: arm64
          - os: ubuntu-latest
            platform: linux
            arch: armhf
            npm_config_arch: arm
          - os: ubuntu-latest
            platform: alpine
            arch: x64
            npm_config_arch: x64
          - os: macos-latest
            platform: darwin
            arch: x64
            npm_config_arch: x64
          - os: macos-latest
            platform: darwin
            arch: arm64
            npm_config_arch: arm64
    steps:
      - uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - uses: ./.github/actions/build-vscode-extension
        with:
          platform: ${{ matrix.platform }}
          arch: ${{ matrix.arch }}
          npm_config_arch: ${{ matrix.npm_config_arch }}
          pre-release: true
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload .vsix artifact
        uses: actions/upload-artifact@v7
        with:
          name: ${{ matrix.platform }}-${{ matrix.arch }}-vsix
          path: "extensions/vscode/*.vsix"

  release:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    needs:
      - build
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Set up Git
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"

      # Download the .vsix artifacts
      - uses: actions/download-artifact@v8
        with:
          pattern: "*-vsix"
          path: vsix-artifacts
          merge-multiple: true

      - name: Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: ${{ github.ref_name }}
          files: |
            vsix-artifacts/*.vsix
          token: ${{ secrets.CI_GITHUB_TOKEN }}
          repository: continuedev/continue
          prerelease: true

  publish:
    runs-on: ubuntu-latest
    needs:
      - build
    if: github.event_name != 'workflow_dispatch' || github.event.inputs.publish_build == 'true'
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      # 1. Download the artifacts
      - uses: actions/download-artifact@v8
        with:
          pattern: "*-vsix"
          path: vsix-artifacts
          merge-multiple: true

      # 2. Publish the extension to VS Code Marketplace
      - name: Publish to VS Code Marketplace
        run: |
          cd extensions/vscode
          npx @vscode/vsce publish --pre-release --packagePath ../../vsix-artifacts/*.vsix
        env:
          VSCE_PAT: ${{ secrets.VSCE_TOKEN }}

      # 3. Publish the extension to Open VSX Registry
      - name: Publish (Open VSX Registry)
        continue-on-error: true
        run: |
          cd extensions/vscode
          npx ovsx publish --pre-release -p ${{ secrets.VSX_REGISTRY_TOKEN }} --packagePath ../../vsix-artifacts/*.vsix

release-config-yaml perms .github/workflows/release-config-yaml.yml
Triggers
push
Runs on
Jobs
release
View raw YAML
name: Release @continuedev/config-yaml

on:
  push:
    branches:
      - main
    paths:
      - "packages/config-yaml/**"
      - ".github/workflows/release-config-yaml.yml"
      - ".github/workflows/reusable-release.yml"

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  release:
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    uses: ./.github/workflows/reusable-release.yml
    with:
      package-name: "config-yaml"
      package-path: "packages/config-yaml"
    secrets:
      SEMANTIC_RELEASE_GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
      SEMANTIC_RELEASE_NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
      MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
      AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
      AZURE_FOUNDRY_CODESTRAL_API_KEY: ${{ secrets.AZURE_FOUNDRY_CODESTRAL_API_KEY }}
      AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY: ${{ secrets.AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY }}
      AZURE_OPENAI_GPT41_API_KEY: ${{ secrets.AZURE_OPENAI_GPT41_API_KEY }}
      VOYAGE_API_KEY: ${{ secrets.VOYAGE_API_KEY }}
      RELACE_API_KEY: ${{ secrets.RELACE_API_KEY }}
      INCEPTION_API_KEY: ${{ secrets.INCEPTION_API_KEY }}
release-fetch perms .github/workflows/release-fetch.yml
Triggers
push
Runs on
Jobs
release
View raw YAML
name: Release @continuedev/fetch

on:
  push:
    branches:
      - main
    paths:
      - "packages/fetch/**"
      - ".github/workflows/release-fetch.yml"
      - ".github/workflows/reusable-release.yml"

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  release:
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    uses: ./.github/workflows/reusable-release.yml
    with:
      package-name: "fetch"
      package-path: "packages/fetch"
    secrets:
      SEMANTIC_RELEASE_GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
      SEMANTIC_RELEASE_NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
      MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
      AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
      AZURE_FOUNDRY_CODESTRAL_API_KEY: ${{ secrets.AZURE_FOUNDRY_CODESTRAL_API_KEY }}
      AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY: ${{ secrets.AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY }}
      AZURE_OPENAI_GPT41_API_KEY: ${{ secrets.AZURE_OPENAI_GPT41_API_KEY }}
      VOYAGE_API_KEY: ${{ secrets.VOYAGE_API_KEY }}
      RELACE_API_KEY: ${{ secrets.RELACE_API_KEY }}
      INCEPTION_API_KEY: ${{ secrets.INCEPTION_API_KEY }}
release-llm-info perms .github/workflows/release-llm-info.yml
Triggers
push
Runs on
Jobs
release
View raw YAML
name: Release @continuedev/llm-info
on:
  push:
    branches:
      - main
    paths:
      - "packages/llm-info/**"
      - ".github/workflows/release-llm-info.yml"
      - ".github/workflows/reusable-release.yml"

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  release:
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    uses: ./.github/workflows/reusable-release.yml
    with:
      package-name: "llm-info"
      package-path: "packages/llm-info"
    secrets:
      SEMANTIC_RELEASE_GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
      SEMANTIC_RELEASE_NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
release-openai-adapters perms .github/workflows/release-openai-adapters.yml
Triggers
push
Runs on
Jobs
release
View raw YAML
name: Release @continuedev/openai-adapters

on:
  push:
    branches:
      - main
    paths:
      - "packages/openai-adapters/**"
      - ".github/workflows/release-openai-adapters.yml"
      - ".github/workflows/reusable-release.yml"

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  release:
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    uses: ./.github/workflows/reusable-release.yml
    with:
      package-name: "openai-adapters"
      package-path: "packages/openai-adapters"
    secrets:
      SEMANTIC_RELEASE_GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
      SEMANTIC_RELEASE_NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
      MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
      AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
      AZURE_FOUNDRY_CODESTRAL_API_KEY: ${{ secrets.AZURE_FOUNDRY_CODESTRAL_API_KEY }}
      AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY: ${{ secrets.AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY }}
      AZURE_OPENAI_GPT41_API_KEY: ${{ secrets.AZURE_OPENAI_GPT41_API_KEY }}
      VOYAGE_API_KEY: ${{ secrets.VOYAGE_API_KEY }}
      RELACE_API_KEY: ${{ secrets.RELACE_API_KEY }}
      INCEPTION_API_KEY: ${{ secrets.INCEPTION_API_KEY }}
reusable-release perms .github/workflows/reusable-release.yml
Triggers
workflow_call
Runs on
ubuntu-latest
Jobs
release
Commands
  • npm ci
  • npm run build
  • npm test
  • npx semantic-release
View raw YAML
name: Reusable Release Workflow

on:
  workflow_call:
    inputs:
      package-name:
        required: true
        type: string
      package-path:
        required: true
        type: string
    secrets:
      SEMANTIC_RELEASE_GITHUB_TOKEN:
        required: true
      SEMANTIC_RELEASE_NPM_TOKEN:
        required: true
      OPENAI_API_KEY:
        required: false
      ANTHROPIC_API_KEY:
        required: false
      GEMINI_API_KEY:
        required: false
      MISTRAL_API_KEY:
        required: false
      AZURE_OPENAI_API_KEY:
        required: false
      AZURE_FOUNDRY_CODESTRAL_API_KEY:
        required: false
      AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY:
        required: false
      AZURE_OPENAI_GPT41_API_KEY:
        required: false
      VOYAGE_API_KEY:
        required: false
      RELACE_API_KEY:
        required: false
      INCEPTION_API_KEY:
        required: false

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  release:
    name: Release ${{ inputs.package-name }}
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ${{ inputs.package-path }}
    steps:
      - name: Checkout
        uses: actions/checkout@v6
        with:
          fetch-depth: 0

      - name: Setup packages
        uses: ./.github/actions/setup-packages

      - name: Use Node.js from .nvmrc
        uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Run tests
        run: npm test
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
          MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
          AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
          AZURE_FOUNDRY_CODESTRAL_API_KEY: ${{ secrets.AZURE_FOUNDRY_CODESTRAL_API_KEY }}
          AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY: ${{ secrets.AZURE_FOUNDRY_MISTRAL_SMALL_API_KEY }}
          AZURE_OPENAI_GPT41_API_KEY: ${{ secrets.AZURE_OPENAI_GPT41_API_KEY }}
          VOYAGE_API_KEY: ${{ secrets.VOYAGE_API_KEY }}
          RELACE_API_KEY: ${{ secrets.RELACE_API_KEY }}
          INCEPTION_API_KEY: ${{ secrets.INCEPTION_API_KEY }}

      - name: Release
        env:
          GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
          NODE_AUTH_TOKEN: ${{ secrets.SEMANTIC_RELEASE_NPM_TOKEN }}
        run: npx semantic-release
run-continue-agent .github/workflows/run-continue-agent.yml
Triggers
workflow_call
Runs on
ubuntu-latest
Jobs
run-agent
Commands
  • # Use jq to properly construct JSON with safe escaping json_body=$(jq -n \ --arg prompt "$PROMPT" \ --arg agent "$AGENT" \ --arg branchName "$BRANCH_NAME" \ --arg repoUrl "$REPO_URL" \ '{prompt: $prompt, agent: $agent, branchName: $branchName, repoUrl: $repoUrl}') response=$(curl -f -X POST https://api.continue.dev/agents \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $CONTINUE_API_KEY" \ -d "$json_body") id=$(echo $response | jq -r '.id') echo "https://continue.dev/hub?type=agents/$id"
View raw YAML
name: Run Continue Agent

on:
  workflow_call:
    inputs:
      prompt:
        description: "Additional prompting to send to the Continue agent"
        required: false
        type: string
        default: ""
      agent:
        description: "The agent to use (e.g., continuedev/github-pr-agent)"
        required: true
        type: string
        default: "continuedev/github-pr-agent"
      branch_name:
        description: "The base branch name to work from"
        required: false
        type: string
        default: "main"
    secrets:
      CONTINUE_API_KEY:
        required: true

jobs:
  run-agent:
    runs-on: ubuntu-latest

    steps:
      - name: Call agents endpoint
        env:
          PROMPT: ${{ inputs.prompt }}
          AGENT: ${{ inputs.agent }}
          BRANCH_NAME: ${{ inputs.branch_name }}
          REPO_URL: https://github.com/${{ github.repository }}
          CONTINUE_API_KEY: ${{ secrets.CONTINUE_API_KEY }}
        run: |
          # Use jq to properly construct JSON with safe escaping
          json_body=$(jq -n \
            --arg prompt "$PROMPT" \
            --arg agent "$AGENT" \
            --arg branchName "$BRANCH_NAME" \
            --arg repoUrl "$REPO_URL" \
            '{prompt: $prompt, agent: $agent, branchName: $branchName, repoUrl: $repoUrl}')

          response=$(curl -f -X POST https://api.continue.dev/agents \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $CONTINUE_API_KEY" \
            -d "$json_body")
          id=$(echo $response | jq -r '.id')
          echo "https://continue.dev/hub?type=agents/$id"
similar-issues .github/workflows/similar-issues.yml
Triggers
issues, pull_request
Runs on
ubuntu-latest
Jobs
analyze
Commands
  • cd deja-view pip install -r requirements.txt
  • cd deja-view # Index the repository (this will update existing index) python cli.py index "${{ github.repository }}" --max-issues 200 || true
  • cd deja-view # Determine if this is an issue or PR if [ "${{ github.event_name }}" = "pull_request" ]; then ISSUE_URL="https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}" THRESHOLD="0.85" TOP_K="5" else ISSUE_URL="https://github.com/${{ github.repository }}/issues/${{ github.event.issue.number }}" THRESHOLD="0.7" TOP_K="5" fi # Create a Python script to search and format as JSON cat << 'PYTHON_SCRIPT' > search_similar.py import sys import json import os from github_similarity_service import SimilarityService issue_url = sys.argv[1] threshold = float(sys.argv[2]) top_k = int(sys.argv[3]) # Parse issue number from URL issue_number = int(issue_url.split('/')[-1]) repo_parts = issue_url.split('/') owner = repo_parts[3] repo = repo_parts[4] service = SimilarityService() # Find similar issues similar = service.find_similar_issues( owner=owner, repo=repo, issue_number=issue_number, top_k=top_k, min_similarity=threshold ) # Format as JSON print(json.dumps(similar)) PYTHON_SCRIPT # Search for similar issues SIMILAR_ISSUES=$(python search_similar.py "$ISSUE_URL" "$THRESHOLD" "$TOP_K") # Save to output echo "similar_issues<<EOF" >> $GITHUB_OUTPUT echo "$SIMILAR_ISSUES" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT # Check if any similar issues found if [ "$(echo "$SIMILAR_ISSUES" | jq '. | length')" -gt 0 ]; then echo "has_similar=true" >> $GITHUB_OUTPUT else echo "has_similar=false" >> $GITHUB_OUTPUT fi
  • cd deja-view # Create a Python script to analyze the issue cat << 'PYTHON_SCRIPT' > check_discussion.py import os import json import re from github_similarity_service import SimilarityService # Get issue details from environment issue_title = os.environ.get('ISSUE_TITLE', '') issue_body = os.environ.get('ISSUE_BODY', '') issue_labels = json.loads(os.environ.get('ISSUE_LABELS', '[]')) # Mock Issue object for analysis class MockIssue: def __init__(self): self.title = issue_title self.body = issue_body self.labels = issue_labels self.state = 'open' self.number = int(os.environ.get('ISSUE_NUMBER', 0)) self.created_at = '' self.updated_at = '' self.url = '' service = SimilarityService() issue = MockIssue() score, reasons = service._calculate_discussion_score(issue) result = { 'score': score, 'reasons': reasons, 'should_be_discussion': score >= 0.5, 'confidence': 'high' if score >= 0.7 else 'medium' if score >= 0.5 else 'low' } print(json.dumps(result)) PYTHON_SCRIPT # Run the analysis DISCUSSION_ANALYSIS=$(ISSUE_TITLE="${{ github.event.issue.title }}" \ ISSUE_BODY='${{ github.event.issue.body }}' \ ISSUE_LABELS='${{ toJson(github.event.issue.labels.*.name) }}' \ ISSUE_NUMBER="${{ github.event.issue.number }}" \ python check_discussion.py) echo "analysis<<EOF" >> $GITHUB_OUTPUT echo "$DISCUSSION_ANALYSIS" >> $GITHUB_OUTPUT echo "EOF" >> $GITHUB_OUTPUT # Extract whether it should be a discussion SHOULD_BE_DISCUSSION=$(echo "$DISCUSSION_ANALYSIS" | jq -r '.should_be_discussion') echo "should_be_discussion=$SHOULD_BE_DISCUSSION" >> $GITHUB_OUTPUT # Extract confidence level CONFIDENCE=$(echo "$DISCUSSION_ANALYSIS" | jq -r '.confidence') echo "confidence=$CONFIDENCE" >> $GITHUB_OUTPUT
View raw YAML
name: Similar Issue Search & Discussion Suggestion
on:
  issues:
    types: [opened]
  pull_request:
    types: [opened]

jobs:
  analyze:
    # Disabling for now due to bugs
    if: false
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write

    steps:
      - name: Checkout deja-view
        uses: actions/checkout@v6
        with:
          repository: "bdougie/deja-view"
          # Option 1: Pin to specific commit (most secure)
          ref: "45e7696" # Pin to specific commit for stability

          # Option 2: Use a tag (recommended after creating releases)
          # ref: 'v1.0.0'

          # Option 3: Use main branch (least secure, gets latest changes)
          # ref: 'main'

          path: deja-view

      - name: Setup Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: |
          cd deja-view
          pip install -r requirements.txt

      - name: Index repository if needed
        env:
          CHROMA_API_KEY: ${{ secrets.CHROMA_CLOUD_API_KEY }}
          CHROMA_TENANT: ${{ secrets.CHROMA_TENANT }}
          CHROMA_DATABASE: ${{ secrets.CHROMA_DATABASE }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          cd deja-view

          # Index the repository (this will update existing index)
          python cli.py index "${{ github.repository }}" --max-issues 200 || true

      - name: Search for similar issues
        id: search
        env:
          CHROMA_API_KEY: ${{ secrets.CHROMA_CLOUD_API_KEY }}
          CHROMA_TENANT: ${{ secrets.CHROMA_TENANT }}
          CHROMA_DATABASE: ${{ secrets.CHROMA_DATABASE }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          cd deja-view

          # Determine if this is an issue or PR
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            ISSUE_URL="https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}"
            THRESHOLD="0.85"
            TOP_K="5"
          else
            ISSUE_URL="https://github.com/${{ github.repository }}/issues/${{ github.event.issue.number }}"
            THRESHOLD="0.7"
            TOP_K="5"
          fi

          # Create a Python script to search and format as JSON
          cat << 'PYTHON_SCRIPT' > search_similar.py
          import sys
          import json
          import os
          from github_similarity_service import SimilarityService

          issue_url = sys.argv[1]
          threshold = float(sys.argv[2])
          top_k = int(sys.argv[3])

          # Parse issue number from URL
          issue_number = int(issue_url.split('/')[-1])
          repo_parts = issue_url.split('/')
          owner = repo_parts[3]
          repo = repo_parts[4]

          service = SimilarityService()

          # Find similar issues
          similar = service.find_similar_issues(
              owner=owner,
              repo=repo,
              issue_number=issue_number,
              top_k=top_k,
              min_similarity=threshold
          )

          # Format as JSON
          print(json.dumps(similar))
          PYTHON_SCRIPT

          # Search for similar issues
          SIMILAR_ISSUES=$(python search_similar.py "$ISSUE_URL" "$THRESHOLD" "$TOP_K")

          # Save to output
          echo "similar_issues<<EOF" >> $GITHUB_OUTPUT
          echo "$SIMILAR_ISSUES" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

          # Check if any similar issues found
          if [ "$(echo "$SIMILAR_ISSUES" | jq '. | length')" -gt 0 ]; then
            echo "has_similar=true" >> $GITHUB_OUTPUT
          else
            echo "has_similar=false" >> $GITHUB_OUTPUT
          fi

      - name: Check if issue should be a discussion
        id: discussion_check
        if: github.event_name == 'issues'
        env:
          CHROMA_API_KEY: ${{ secrets.CHROMA_CLOUD_API_KEY }}
          CHROMA_TENANT: ${{ secrets.CHROMA_TENANT }}
          CHROMA_DATABASE: ${{ secrets.CHROMA_DATABASE }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          cd deja-view

          # Create a Python script to analyze the issue
          cat << 'PYTHON_SCRIPT' > check_discussion.py
          import os
          import json
          import re
          from github_similarity_service import SimilarityService

          # Get issue details from environment
          issue_title = os.environ.get('ISSUE_TITLE', '')
          issue_body = os.environ.get('ISSUE_BODY', '')
          issue_labels = json.loads(os.environ.get('ISSUE_LABELS', '[]'))

          # Mock Issue object for analysis
          class MockIssue:
              def __init__(self):
                  self.title = issue_title
                  self.body = issue_body
                  self.labels = issue_labels
                  self.state = 'open'
                  self.number = int(os.environ.get('ISSUE_NUMBER', 0))
                  self.created_at = ''
                  self.updated_at = ''
                  self.url = ''

          service = SimilarityService()
          issue = MockIssue()

          score, reasons = service._calculate_discussion_score(issue)

          result = {
              'score': score,
              'reasons': reasons,
              'should_be_discussion': score >= 0.5,
              'confidence': 'high' if score >= 0.7 else 'medium' if score >= 0.5 else 'low'
          }

          print(json.dumps(result))
          PYTHON_SCRIPT

          # Run the analysis
          DISCUSSION_ANALYSIS=$(ISSUE_TITLE="${{ github.event.issue.title }}" \
            ISSUE_BODY='${{ github.event.issue.body }}' \
            ISSUE_LABELS='${{ toJson(github.event.issue.labels.*.name) }}' \
            ISSUE_NUMBER="${{ github.event.issue.number }}" \
            python check_discussion.py)

          echo "analysis<<EOF" >> $GITHUB_OUTPUT
          echo "$DISCUSSION_ANALYSIS" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

          # Extract whether it should be a discussion
          SHOULD_BE_DISCUSSION=$(echo "$DISCUSSION_ANALYSIS" | jq -r '.should_be_discussion')
          echo "should_be_discussion=$SHOULD_BE_DISCUSSION" >> $GITHUB_OUTPUT

          # Extract confidence level
          CONFIDENCE=$(echo "$DISCUSSION_ANALYSIS" | jq -r '.confidence')
          echo "confidence=$CONFIDENCE" >> $GITHUB_OUTPUT

      - name: Comment with analysis
        uses: actions/github-script@v8
        with:
          script: |
            let comment = '';
            const hasSimilar = '${{ steps.search.outputs.has_similar }}' === 'true';
            const isPR = '${{ github.event_name }}' === 'pull_request';
            const shouldBeDiscussion = !isPR && '${{ steps.discussion_check.outputs.should_be_discussion }}' === 'true';

            // Add similar issues section if found
            if (hasSimilar) {
              const similarIssues = JSON.parse(`${{ steps.search.outputs.similar_issues }}`);
              
              if (isPR) {
                // Filter only open issues for PRs
                const openIssues = similarIssues.filter(issue => issue.state === 'open');
                
                if (openIssues.length > 0) {
                  // Simple table format for PRs
                  comment += '## 📋 Related Open Issues\n\n';
                  comment += 'These open issues appear to be related to this PR (≥85% similarity):\n\n';
                  comment += '| # | Title | Similarity |\n';
                  comment += '|---|-------|------------|\n';
                  
                  openIssues.forEach(issue => {
                    const similarity = (issue.similarity * 100).toFixed(0);
                    const title = issue.title.length > 50 ? issue.title.substring(0, 47) + '...' : issue.title;
                    comment += `| [#${issue.number}](${issue.url}) | ${title} | ${similarity}% |\n`;
                  });
                  
                  comment += '\n';
                  comment += '_Consider closing related issues if this PR addresses them._\n';
                } else {
                  // Don't add any comment if no open issues found
                  return;
                }
              } else {
                // Original format for issues
                comment += '## 🔍 Similar Issues Found\n\n';
                comment += 'I found some existing issues that might be related:\n\n';
                
                similarIssues.forEach((issue, index) => {
                  const similarity = (issue.similarity * 100).toFixed(1);
                  const state = issue.state === 'open' ? '🟢' : '🔴';
                  
                  comment += `${index + 1}. ${state} [#${issue.number}: ${issue.title}](${issue.url}) (${similarity}% similar)\n`;
                  
                  if (issue.summary) {
                    comment += `   > ${issue.summary.substring(0, 150)}${issue.summary.length > 150 ? '...' : ''}\n`;
                  }
                  comment += '\n';
                });
                
                comment += '\n';
              }
            }

            // Add discussion suggestion if applicable
            if (shouldBeDiscussion) {
              const analysis = JSON.parse(`${{ steps.discussion_check.outputs.analysis }}`);
              const confidence = '${{ steps.discussion_check.outputs.confidence }}';
              
              if (hasSimilar) {
                comment += '---\n\n';
              }
              
              comment += '## 💬 Discussion Suggestion\n\n';
              
              const confidenceEmoji = {
                'high': '🟢',
                'medium': '🟡',
                'low': '🔴'
              };
              
              comment += `This issue might be better suited as a **GitHub Discussion** ${confidenceEmoji[confidence] || ''}\n\n`;
              comment += `**Confidence**: ${confidence.charAt(0).toUpperCase() + confidence.slice(1)} (${(analysis.score * 100).toFixed(0)}%)\n\n`;
              
              if (analysis.reasons && analysis.reasons.length > 0) {
                comment += '**Reasons**:\n';
                analysis.reasons.forEach(reason => {
                  comment += `- ${reason}\n`;
                });
                comment += '\n';
              }
              
              comment += 'GitHub Discussions are great for:\n';
              comment += '- Questions and help requests\n';
              comment += '- Feature requests and ideas\n';
              comment += '- General feedback and brainstorming\n';
              comment += '- Community conversations\n\n';
              
              comment += '_Consider converting this to a discussion if it\'s not a bug report or actionable task._\n';
            }

            // Only comment if we have something to say
            if (comment) {
              comment += '\n---\n';
              comment += '_This analysis was automatically generated by [deja-view](https://github.com/bdougie/deja-view)._';
              
              if ('${{ github.event_name }}' === 'pull_request') {
                await github.rest.issues.createComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: context.payload.pull_request.number,
                  body: comment
                });
              } else {
                await github.rest.issues.createComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: context.issue.number,
                  body: comment
                });
              }
            }

      - name: Add labels
        if: github.event_name == 'issues'
        uses: actions/github-script@v8
        with:
          script: |
            const labels = [];

            // Check for duplicate
            if ('${{ steps.search.outputs.has_similar }}' === 'true') {
              const similarIssues = JSON.parse(`${{ steps.search.outputs.similar_issues }}`);
              const hasDuplicate = similarIssues.some(issue => issue.similarity > 0.9);
              
              if (hasDuplicate) {
                labels.push('potential-duplicate');
              }
            }

            // Check for discussion suggestion
            if ('${{ steps.discussion_check.outputs.should_be_discussion }}' === 'true') {
              const confidence = '${{ steps.discussion_check.outputs.confidence }}';
              
              if (confidence === 'high') {
                labels.push('should-be-discussion');
              } else if (confidence === 'medium') {
                labels.push('discussion');
              }
            }

            // Add labels if any
            if (labels.length > 0) {
              await github.rest.issues.addLabels({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.issue.number,
                labels: labels
              });
            }
snyk-agent .github/workflows/snyk-agent.yaml
Triggers
schedule, workflow_dispatch
Runs on
ubuntu-latest
Jobs
run-cn-task
Commands
  • npm install -g @continuedev/cli@latest
  • cd extensions/cli && cn -p --agent continuedev/snyk-code-scan-agent "The current directory"
View raw YAML
name: Daily Snyk Agent

on:
  schedule:
    # Runs at 9:00 AM UTC every day
    - cron: "0 9 * * *"
  workflow_dispatch: # Allows manual triggering

jobs:
  run-cn-task:
    runs-on: ubuntu-latest
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: "20"

      - name: Install Continue CLI globally
        run: npm install -g @continuedev/cli@latest

      - name: Run Snyk Agent
        run: cd extensions/cli && cn -p --agent continuedev/snyk-code-scan-agent "The current directory"
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
          CONTINUE_API_KEY: ${{ secrets.CONTINUE_API_KEY }}
stable-release perms .github/workflows/stable-release.yml
Triggers
workflow_dispatch
Runs on
ubuntu-latest
Jobs
stable-release
Commands
  • cd core npm run build
  • npm ci
  • npm version ${{ inputs.stable_version }} --no-git-tag-version
  • npm run build
  • npm test
  • unset NODE_AUTH_TOKEN npm publish --tag latest --provenance echo "Published version: ${{ inputs.stable_version }}"
  • git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git tag "v${{ inputs.stable_version }}" git push origin "v${{ inputs.stable_version }}" gh release create "v${{ inputs.stable_version }}" \ --title "CLI Release v${{ inputs.stable_version }}" \ --notes "Release v${{ inputs.stable_version }} built and published from the main branch." \ --latest
  • publish_blueprint() { local name=$1 local template=$2 echo "Publishing blueprint '$name' to Runloop API for version ${{ inputs.stable_version }}" # Use blueprint configuration from template file cp ".github/workflows/$template" blueprint.json # Publish to Runloop API response=$(curl -X POST "https://api.runloop.ai/v1/blueprints" \ -H "Authorization: Bearer $RUNLOOP_API_KEY" \ -H "Content-Type: application/json" \ -d @blueprint.json \ -w "%{http_code}" \ -s) http_code=$(echo "$response" | tail -c 4) response_body=$(echo "$response" | head -c -4) if [[ "$http_code" == "200" ]] || [[ "$http_code" == "201" ]]; then echo "✅ Successfully published blueprint '$name' to Runloop API" echo "Response: $response_body" blueprint_id=$(echo "$response_body" | jq -r '.id // empty') if [[ -n "$blueprint_id" ]]; then echo "Blueprint ID: $blueprint_id" fi else echo "❌ Failed to publish blueprint '$name' to Runloop API" echo "HTTP Code: $http_code" echo "Response: $response_body" exit 1 fi } # Publish both cn and cn-staging blueprints publish_blueprint "cn" "runloop-blueprint-template.json" publish_blueprint "cn-staging" "runloop-blueprint-staging-template.json"
View raw YAML
name: Stable Release

on:
  workflow_dispatch:
    inputs:
      stable_version:
        description: "Version for stable release (e.g., 1.2.3)"
        required: true
        type: string

permissions:
  contents: write
  issues: write
  pull-requests: write
  id-token: write  # Required for OIDC

jobs:
  stable-release:
    name: Stable Release
    runs-on: ubuntu-latest
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    steps:
      - name: Checkout
        uses: actions/checkout@v6
        with:
          fetch-depth: 0
          token: ${{ secrets.SEMANTIC_RELEASE_TOKEN }}

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 20

      - name: Setup packages
        uses: ./.github/actions/setup-packages

      - name: Setup core component
        uses: ./.github/actions/setup-component
        with:
          component: core
          include-root: true

      - name: Build core
        run: |
          cd core
          npm run build

      - name: Install CLI dependencies
        working-directory: extensions/cli
        run: npm ci

      - name: Update version
        working-directory: extensions/cli
        run: npm version ${{ inputs.stable_version }} --no-git-tag-version

      - name: Build
        working-directory: extensions/cli
        run: npm run build

      - name: Run tests
        working-directory: extensions/cli
        run: npm test

      - name: Setup Node.js for OIDC publish
        uses: actions/setup-node@v6
        with:
          node-version: 24
          registry-url: "https://registry.npmjs.org"

      - name: Publish to npm
        working-directory: extensions/cli
        run: |
          unset NODE_AUTH_TOKEN
          npm publish --tag latest --provenance
          echo "Published version: ${{ inputs.stable_version }}"

      - name: Create release on GitHub
        env:
          GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN }}
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"
          git tag "v${{ inputs.stable_version }}"
          git push origin "v${{ inputs.stable_version }}"

          gh release create "v${{ inputs.stable_version }}" \
            --title "CLI Release v${{ inputs.stable_version }}" \
            --notes "Release v${{ inputs.stable_version }} built and published from the main branch." \
            --latest

      - name: Publish Blueprints to Runloop
        env:
          RUNLOOP_API_KEY: ${{ secrets.RUNLOOP_API_KEY }}
        run: |
          publish_blueprint() {
            local name=$1
            local template=$2

            echo "Publishing blueprint '$name' to Runloop API for version ${{ inputs.stable_version }}"

            # Use blueprint configuration from template file
            cp ".github/workflows/$template" blueprint.json

            # Publish to Runloop API
            response=$(curl -X POST "https://api.runloop.ai/v1/blueprints" \
              -H "Authorization: Bearer $RUNLOOP_API_KEY" \
              -H "Content-Type: application/json" \
              -d @blueprint.json \
              -w "%{http_code}" \
              -s)

            http_code=$(echo "$response" | tail -c 4)
            response_body=$(echo "$response" | head -c -4)

            if [[ "$http_code" == "200" ]] || [[ "$http_code" == "201" ]]; then
              echo "✅ Successfully published blueprint '$name' to Runloop API"
              echo "Response: $response_body"

              blueprint_id=$(echo "$response_body" | jq -r '.id // empty')
              if [[ -n "$blueprint_id" ]]; then
                echo "Blueprint ID: $blueprint_id"
              fi
            else
              echo "❌ Failed to publish blueprint '$name' to Runloop API"
              echo "HTTP Code: $http_code"
              echo "Response: $response_body"
              exit 1
            fi
          }

          # Publish both cn and cn-staging blueprints
          publish_blueprint "cn" "runloop-blueprint-template.json"
          publish_blueprint "cn-staging" "runloop-blueprint-staging-template.json"
stale-issue-helper .github/workflows/stale-issue-helper.yaml
Triggers
schedule
Runs on
ubuntu-latest
Jobs
stale
Actions
actions/stale
View raw YAML
name: "Label / close stale issues"
on:
  schedule:
    - cron: "30 1 * * *"

jobs:
  stale:
    permissions:
      issues: write
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v10
        with:
          close-issue-message: "This issue was closed because it wasn't updated for 10 days after being marked stale. If it's still important, please reopen + comment and we'll gladly take another look!"
          stale-issue-message: "This issue hasn't been updated in 90 days and will be closed after an additional 10 days without activity. If it's still important, please leave a comment and share any new information that would help us address the issue."
          days-before-stale: 90
          days-before-close: 10
          days-before-pr-stale: -1
          days-before-pr-close: -1
          operations-per-run: 1000
          stale-issue-label: "stale"
          stale-pr-label: "stale"
          exempt-issue-labels: "needs-triage,no-stale,high,highest"
          exempt-pr-labels: "no-stale"
submit-github-dependency-graph perms .github/workflows/submit-github-dependency-graph.yml
Triggers
push
Runs on
ubuntu-latest
Jobs
dependency-submission
Actions
gradle/actions/dependency-submission
View raw YAML
name: Submit Gradle Dependency Graph For Dependabot

on:
  push:
    branches: ["main"]

permissions:
  contents: write

jobs:
  dependency-submission:
    runs-on: ubuntu-latest
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    steps:
      - name: Checkout sources
        uses: actions/checkout@v6
      - name: Setup Java
        uses: actions/setup-java@v5
        with:
          distribution: "temurin"
          java-version: 17
      - name: Generate and submit dependency graph
        uses: gradle/actions/dependency-submission@v6
        with:
          # The gradle project is not in the root of the repository.
          build-root-directory: extensions/intellij
tidy-up-codebase .github/workflows/tidy-up-codebase.yml
Triggers
schedule, workflow_dispatch
Runs on
Jobs
run-cn-task
View raw YAML
name: Weekly CN Task

on:
  schedule:
    # Runs at 8/9:30 AM PST (16:30 UTC) every Monday so PR shows up at beginning of week
    - cron: "30 16 * * 1"
  workflow_dispatch: # Allows manual triggering

jobs:
  run-cn-task:
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    uses: ./.github/workflows/run-continue-agent.yml
    with:
      agent: continuedev/tidy-up-markdown-agent
      branch_name: main
    secrets:
      CONTINUE_API_KEY: ${{ secrets.CONTINUE_API_KEY }}
upload-runloop-blueprint matrix perms .github/workflows/upload-runloop-blueprint.yml
Triggers
workflow_dispatch, push
Runs on
ubuntu-latest
Jobs
upload-blueprints
Matrix
include, include.name, include.template→ cn, cn-staging, runloop-blueprint-staging-template.json, runloop-blueprint-template.json
Commands
  • echo "Publishing blueprint '${{ matrix.name }}' to Runloop API" # Use blueprint configuration from template file cp .github/workflows/${{ matrix.template }} blueprint.json # Publish to Runloop API response=$(curl -X POST "https://api.runloop.ai/v1/blueprints" \ -H "Authorization: Bearer $RUNLOOP_API_KEY" \ -H "Content-Type: application/json" \ -d @blueprint.json \ -w "%{http_code}" \ -s) http_code=$(echo "$response" | tail -c 4) response_body=$(echo "$response" | head -c -4) if [[ "$http_code" == "200" ]] || [[ "$http_code" == "201" ]]; then echo "✅ Successfully published blueprint '${{ matrix.name }}' to Runloop API" echo "Response: $response_body" # Extract blueprint ID if available blueprint_id=$(echo "$response_body" | jq -r '.id // empty') if [[ -n "$blueprint_id" ]]; then echo "Blueprint ID: $blueprint_id" echo "blueprint_id=$blueprint_id" >> $GITHUB_OUTPUT fi else echo "❌ Failed to publish blueprint '${{ matrix.name }}' to Runloop API" echo "HTTP Code: $http_code" echo "Response: $response_body" exit 1 fi
View raw YAML
name: Upload Runloop Blueprint

on:
  workflow_dispatch:
  push:
    branches:
      - main
    paths:
      - '.github/workflows/runloop-blueprint-template.json'
      - '.github/workflows/runloop-blueprint-staging-template.json'

permissions:
  contents: read

jobs:
  upload-blueprints:
    name: Upload Blueprints to Runloop
    runs-on: ubuntu-latest
    # Only run this workflow on the main repository (continuedev/continue)
    if: github.repository == 'continuedev/continue'
    strategy:
      matrix:
        include:
          - template: runloop-blueprint-template.json
            name: cn
          - template: runloop-blueprint-staging-template.json
            name: cn-staging
    steps:
      - name: Checkout
        uses: actions/checkout@v6

      - name: Publish ${{ matrix.name }} Blueprint to Runloop
        env:
          RUNLOOP_API_KEY: ${{ secrets.RUNLOOP_API_KEY }}
        run: |
          echo "Publishing blueprint '${{ matrix.name }}' to Runloop API"

          # Use blueprint configuration from template file
          cp .github/workflows/${{ matrix.template }} blueprint.json

          # Publish to Runloop API
          response=$(curl -X POST "https://api.runloop.ai/v1/blueprints" \
            -H "Authorization: Bearer $RUNLOOP_API_KEY" \
            -H "Content-Type: application/json" \
            -d @blueprint.json \
            -w "%{http_code}" \
            -s)

          http_code=$(echo "$response" | tail -c 4)
          response_body=$(echo "$response" | head -c -4)

          if [[ "$http_code" == "200" ]] || [[ "$http_code" == "201" ]]; then
            echo "✅ Successfully published blueprint '${{ matrix.name }}' to Runloop API"
            echo "Response: $response_body"

            # Extract blueprint ID if available
            blueprint_id=$(echo "$response_body" | jq -r '.id // empty')
            if [[ -n "$blueprint_id" ]]; then
              echo "Blueprint ID: $blueprint_id"
              echo "blueprint_id=$blueprint_id" >> $GITHUB_OUTPUT
            fi
          else
            echo "❌ Failed to publish blueprint '${{ matrix.name }}' to Runloop API"
            echo "HTTP Code: $http_code"
            echo "Response: $response_body"
            exit 1
          fi
vscode-prerelease perms .github/workflows/vscode-prerelease.yml
Triggers
workflow_dispatch
Runs on
ubuntu-latest
Jobs
create-prerelease
Commands
  • # Get current version from package.json CURRENT_VERSION=$(node -p "require('./package.json').version") echo "Current version in package.json: $CURRENT_VERSION" # Determine new pre-release version if [[ -n "${{ inputs.prerelease_version }}" ]]; then NEW_VERSION="${{ inputs.prerelease_version }}" echo "Using manually specified new version: $NEW_VERSION" else # Auto-increment patch version IFS='.' read -r major minor patch <<< "$CURRENT_VERSION" NEW_PATCH=$((patch + 1)) NEW_VERSION="${major}.${minor}.${NEW_PATCH}" echo "Auto-incremented version: $NEW_VERSION" fi TAG_NAME="v${NEW_VERSION}-vscode" echo "previous_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT echo "Summary:" echo " Previous version: $CURRENT_VERSION" echo " New version: $NEW_VERSION" echo " Tag name: $TAG_NAME"
  • BRANCH_NAME="prerelease/vscode-${{ steps.version.outputs.new_version }}" echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git checkout -b "$BRANCH_NAME" echo "Created branch: $BRANCH_NAME"
  • # Update version in package.json npm version ${{ steps.version.outputs.new_version }} --no-git-tag-version echo "Updated package.json to version ${{ steps.version.outputs.new_version }}"
  • git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add extensions/vscode/package.json git commit -m "chore: bump VSCode extension version to ${{ steps.version.outputs.new_version }}" echo "Committed version bump"
  • git push origin "${{ steps.branch.outputs.branch_name }}" echo "Pushed branch: ${{ steps.branch.outputs.branch_name }}" # Create pull request PR_URL=$(gh pr create \ --base main \ --head "${{ steps.branch.outputs.branch_name }}" \ --title "chore: VSCode pre-release ${{ steps.version.outputs.new_version }}" \ --body "$(cat <<'EOF' ## VSCode Pre-release ${{ steps.version.outputs.new_version }} This PR bumps the VSCode extension version for pre-release. ### Changes - Version bumped from ${{ steps.version.outputs.previous_version }} to ${{ steps.version.outputs.new_version }} - Based on commit: ${{ inputs.main_commit_sha }} ### Release Process After merging this PR: 1. The tag \`${{ steps.version.outputs.tag_name }}\` will be created automatically 2. A GitHub pre-release will be created with auto-generated release notes 🤖 This PR was created automatically by the VSCode Pre-release workflow. EOF )") echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT echo "Created PR: $PR_URL"
  • # Get PR number from URL PR_NUMBER=$(echo "${{ steps.pr.outputs.pr_url }}" | grep -oE '[0-9]+$') # Merge the PR gh pr merge "$PR_NUMBER" --squash --auto echo "PR #$PR_NUMBER set to auto-merge" # Wait for merge to complete (with timeout) echo "Waiting for PR to be merged..." TIMEOUT=300 # 5 minutes ELAPSED=0 INTERVAL=10 while [ $ELAPSED -lt $TIMEOUT ]; do PR_STATE=$(gh pr view "$PR_NUMBER" --json state --jq '.state') if [ "$PR_STATE" = "MERGED" ]; then echo "PR successfully merged!" break fi sleep $INTERVAL ELAPSED=$((ELAPSED + INTERVAL)) echo "Still waiting... ($ELAPSED seconds elapsed)" done if [ $ELAPSED -ge $TIMEOUT ]; then echo "Warning: Timed out waiting for PR merge. Please check manually." && exit 1 fi
  • git fetch origin main git checkout main git pull origin main
  • git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git tag "${{ steps.version.outputs.tag_name }}" git push origin "${{ steps.version.outputs.tag_name }}" echo "Created and pushed tag: ${{ steps.version.outputs.tag_name }}"
View raw YAML
name: VSCode Pre-release

on:
  workflow_dispatch:
    inputs:
      main_commit_sha:
        description: "Main branch commit SHA to create pre-release from - leave empty to use HEAD of main"
        required: false
        type: string
      prerelease_version:
        description: "New pre-release version (e.g., 1.3.15) - leave empty to auto-increment"
        required: false
        type: string

permissions:
  contents: write
  pull-requests: write

jobs:
  create-prerelease:
    name: Create VSCode Pre-release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          ref: ${{ inputs.main_commit_sha || 'main' }}
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Node.js
        uses: actions/setup-node@v6
        with:
          node-version: 20

      - name: Determine version numbers
        id: version
        working-directory: extensions/vscode
        run: |
          # Get current version from package.json
          CURRENT_VERSION=$(node -p "require('./package.json').version")
          echo "Current version in package.json: $CURRENT_VERSION"

          # Determine new pre-release version
          if [[ -n "${{ inputs.prerelease_version }}" ]]; then
            NEW_VERSION="${{ inputs.prerelease_version }}"
            echo "Using manually specified new version: $NEW_VERSION"
          else
            # Auto-increment patch version
            IFS='.' read -r major minor patch <<< "$CURRENT_VERSION"
            NEW_PATCH=$((patch + 1))
            NEW_VERSION="${major}.${minor}.${NEW_PATCH}"
            echo "Auto-incremented version: $NEW_VERSION"
          fi

          TAG_NAME="v${NEW_VERSION}-vscode"

          echo "previous_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
          echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
          echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT

          echo "Summary:"
          echo "  Previous version: $CURRENT_VERSION"
          echo "  New version: $NEW_VERSION"
          echo "  Tag name: $TAG_NAME"

      - name: Create pre-release branch
        id: branch
        run: |
          BRANCH_NAME="prerelease/vscode-${{ steps.version.outputs.new_version }}"
          echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT

          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"

          git checkout -b "$BRANCH_NAME"
          echo "Created branch: $BRANCH_NAME"

      - name: Update package.json version
        working-directory: extensions/vscode
        run: |
          # Update version in package.json
          npm version ${{ steps.version.outputs.new_version }} --no-git-tag-version

          echo "Updated package.json to version ${{ steps.version.outputs.new_version }}"

      - name: Commit version bump
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"

          git add extensions/vscode/package.json
          git commit -m "chore: bump VSCode extension version to ${{ steps.version.outputs.new_version }}"

          echo "Committed version bump"

      - name: Push branch and create PR
        id: pr
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          git push origin "${{ steps.branch.outputs.branch_name }}"
          echo "Pushed branch: ${{ steps.branch.outputs.branch_name }}"

          # Create pull request
          PR_URL=$(gh pr create \
            --base main \
            --head "${{ steps.branch.outputs.branch_name }}" \
            --title "chore: VSCode pre-release ${{ steps.version.outputs.new_version }}" \
            --body "$(cat <<'EOF'
          ## VSCode Pre-release ${{ steps.version.outputs.new_version }}

          This PR bumps the VSCode extension version for pre-release.

          ### Changes
          - Version bumped from ${{ steps.version.outputs.previous_version }} to ${{ steps.version.outputs.new_version }}
          - Based on commit: ${{ inputs.main_commit_sha }}

          ### Release Process
          After merging this PR:
          1. The tag \`${{ steps.version.outputs.tag_name }}\` will be created automatically
          2. A GitHub pre-release will be created with auto-generated release notes

          🤖 This PR was created automatically by the VSCode Pre-release workflow.
          EOF
          )")

          echo "pr_url=$PR_URL" >> $GITHUB_OUTPUT
          echo "Created PR: $PR_URL"

      - name: Auto-merge PR
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Get PR number from URL
          PR_NUMBER=$(echo "${{ steps.pr.outputs.pr_url }}" | grep -oE '[0-9]+$')

          # Merge the PR
          gh pr merge "$PR_NUMBER" --squash --auto

          echo "PR #$PR_NUMBER set to auto-merge"

          # Wait for merge to complete (with timeout)
          echo "Waiting for PR to be merged..."
          TIMEOUT=300  # 5 minutes
          ELAPSED=0
          INTERVAL=10

          while [ $ELAPSED -lt $TIMEOUT ]; do
            PR_STATE=$(gh pr view "$PR_NUMBER" --json state --jq '.state')
            if [ "$PR_STATE" = "MERGED" ]; then
              echo "PR successfully merged!"
              break
            fi
            sleep $INTERVAL
            ELAPSED=$((ELAPSED + INTERVAL))
            echo "Still waiting... ($ELAPSED seconds elapsed)"
          done

          if [ $ELAPSED -ge $TIMEOUT ]; then
            echo "Warning: Timed out waiting for PR merge. Please check manually." && exit 1
          fi

      - name: Checkout main branch
        run: |
          git fetch origin main
          git checkout main
          git pull origin main

      - name: Create and push tag
        run: |
          git config --local user.email "action@github.com"
          git config --local user.name "GitHub Action"

          git tag "${{ steps.version.outputs.tag_name }}"
          git push origin "${{ steps.version.outputs.tag_name }}"

          echo "Created and pushed tag: ${{ steps.version.outputs.tag_name }}"

      - name: Get previous tag for release notes
        id: prev_tag
        run: |
          # Find the previous vscode pre-release tag
          PREV_TAG=$(git tag -l "v*-vscode" --sort=-version:refname | head -n 2 | tail -n 1)

          if [ -z "$PREV_TAG" ]; then
            echo "No previous tag found, using first commit"
            PREV_TAG=$(git rev-list --max-parents=0 HEAD)
          fi

          echo "prev_tag=$PREV_TAG" >> $GITHUB_OUTPUT
          echo "Previous tag for release notes: $PREV_TAG"

      - name: Create GitHub pre-release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # Generate release notes between previous tag and current tag
          RELEASE_NOTES=$(gh api \
            --method POST \
            -H "Accept: application/vnd.github+json" \
            /repos/${{ github.repository }}/releases/generate-notes \
            -f tag_name="${{ steps.version.outputs.tag_name }}" \
            -f target_commitish="main" \
            -f previous_tag_name="${{ steps.prev_tag.outputs.prev_tag }}" \
            --jq '.body')

          # Create the pre-release
          gh release create "${{ steps.version.outputs.tag_name }}" \
            --title "VSCode Pre-release ${{ steps.version.outputs.new_version }}" \
            --notes "$RELEASE_NOTES" \
            --prerelease \
            --target main

          echo "Created pre-release: ${{ steps.version.outputs.tag_name }}"

      - name: Summary
        run: |
          echo "## VSCode Pre-release Created Successfully! 🚀" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Version Information" >> $GITHUB_STEP_SUMMARY
          echo "- **Previous Version:** ${{ steps.version.outputs.previous_version }}" >> $GITHUB_STEP_SUMMARY
          echo "- **New Version:** ${{ steps.version.outputs.new_version }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Tag:** \`${{ steps.version.outputs.tag_name }}\`" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Links" >> $GITHUB_STEP_SUMMARY
          echo "- **PR:** ${{ steps.pr.outputs.pr_url }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Release:** https://github.com/${{ github.repository }}/releases/tag/${{ steps.version.outputs.tag_name }}" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Commit" >> $GITHUB_STEP_SUMMARY
          echo "- **Base Commit:** \`${{ inputs.main_commit_sha }}\`" >> $GITHUB_STEP_SUMMARY
vscode-version-bump .github/workflows/vscode-version-bump.yml
Triggers
workflow_dispatch
Runs on
ubuntu-latest
Jobs
version-bump
Commands
  • gh auth login --with-token <<< "${{ github.token }}"
  • echo "Starting version bump process..." # Find last v1.1.x-vscode tag that's at least 6 days old CURRENT_TIMESTAMP=$(date +%s) SIX_DAYS_AGO=$((CURRENT_TIMESTAMP - 6*24*60*60)) echo "Current timestamp: $(date -d @${CURRENT_TIMESTAMP})" echo "Six days ago: $(date -d @${SIX_DAYS_AGO})" echo "Looking for v1.1.x-vscode tags..." git for-each-ref --sort=-creatordate --format '%(refname:short) %(creatordate:iso)' refs/tags | grep 'v1\.1\.[0-9]\+-vscode' || echo "No matching tags found" LAST_1_1_TAG=$(git for-each-ref --sort=-creatordate --format '%(refname:short) %(creatordate:unix)' refs/tags \ | grep 'v1\.1\.[0-9]\+-vscode' \ | while read tag timestamp; do if [ $timestamp -le $SIX_DAYS_AGO ]; then echo ${tag% *} break fi done) echo "Selected v1.1.x tag: $LAST_1_1_TAG" if [ -z "$LAST_1_1_TAG" ]; then echo "::error::No suitable v1.1.x-vscode tag found" exit 1 fi # Find last v1.0.y-vscode tag echo "Looking for v1.0.y-vscode tags..." git tag --sort=-v:refname | grep '^v1\.0\.[0-9]\+-vscode' || echo "No matching tags found" LAST_1_0_TAG=$(git tag --sort=-v:refname | grep '^v1\.0\.[0-9]\+-vscode' | head -n1) echo "Selected v1.0.y tag: $LAST_1_0_TAG" if [ -z "$LAST_1_0_TAG" ]; then echo "::error::No v1.0.y-vscode tag found" exit 1 fi # Extract the y number and increment it Y_NUMBER=$(echo $LAST_1_0_TAG | sed 's/v1\.0\.\([0-9]\+\)-vscode/\1/') NEXT_Y=$((Y_NUMBER + 1)) NEW_BRANCH="v1.0.${NEXT_Y}-vscode" NEW_VERSION="1.0.${NEXT_Y}" echo "Current Y number: $Y_NUMBER" echo "Next Y number: $NEXT_Y" echo "New branch name: $NEW_BRANCH" echo "New version: $NEW_VERSION" # Create new branch from the v1.1.x tag echo "Creating new branch from $LAST_1_1_TAG..." git checkout $LAST_1_1_TAG git checkout -b $NEW_BRANCH # Update the version in package.json echo "Current package.json version:" cat extensions/vscode/package.json | grep version echo "Updating version in package.json..." jq ".version = \"$NEW_VERSION\"" extensions/vscode/package.json > temp.json && mv temp.json extensions/vscode/package.json echo "New package.json version:" cat extensions/vscode/package.json | grep version # Configure git echo "Configuring git..." git config user.name "GitHub Actions Bot" git config user.email "actions@github.com" # Commit and push changes echo "Committing changes..." git add extensions/vscode/package.json git commit -m "Bump VS Code extension to ${NEW_VERSION}" echo "Pushing branch to origin..." git push origin $NEW_BRANCH # Add release creation echo "Creating draft release..." gh release create "${NEW_BRANCH}" \ --title "${NEW_BRANCH}" \ --generate-notes \ --draft \ --latest \ --notes-start-tag "${LAST_1_0_TAG}" echo "Version bump process completed successfully!"
  • echo "::error::Failed to process version tags and create new branch" echo "Last few lines of git log:" git log -n 5 --oneline echo "Current git status:" git status echo "Current branches:" git branch -a
View raw YAML
name: Create VS Code main release draft
on:
  # Not using this now because making drafts was just noisy. Will be useful when we are ready for automated releases.
  # schedule:
  #   # Runs at 7 AM PST (15:00 UTC) every Friday
  #   - cron: "0 15 * * 5"
  workflow_dispatch:
    # Allows manual triggering

jobs:
  version-bump:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 0 # Fetch all history and tags

      - name: Setup GitHub CLI
        run: |
          gh auth login --with-token <<< "${{ github.token }}"

      - name: Use Node.js from .nvmrc
        uses: actions/setup-node@v6
        with:
          node-version-file: ".nvmrc"

      - name: Find and process version tags
        run: |
          echo "Starting version bump process..."

          # Find last v1.1.x-vscode tag that's at least 6 days old
          CURRENT_TIMESTAMP=$(date +%s)
          SIX_DAYS_AGO=$((CURRENT_TIMESTAMP - 6*24*60*60))
          echo "Current timestamp: $(date -d @${CURRENT_TIMESTAMP})"
          echo "Six days ago: $(date -d @${SIX_DAYS_AGO})"

          echo "Looking for v1.1.x-vscode tags..."
          git for-each-ref --sort=-creatordate --format '%(refname:short) %(creatordate:iso)' refs/tags | grep 'v1\.1\.[0-9]\+-vscode' || echo "No matching tags found"

          LAST_1_1_TAG=$(git for-each-ref --sort=-creatordate --format '%(refname:short) %(creatordate:unix)' refs/tags \
            | grep 'v1\.1\.[0-9]\+-vscode' \
            | while read tag timestamp; do
                if [ $timestamp -le $SIX_DAYS_AGO ]; then
                  echo ${tag% *}
                  break
                fi
              done)

          echo "Selected v1.1.x tag: $LAST_1_1_TAG"
          if [ -z "$LAST_1_1_TAG" ]; then
            echo "::error::No suitable v1.1.x-vscode tag found"
            exit 1
          fi

          # Find last v1.0.y-vscode tag
          echo "Looking for v1.0.y-vscode tags..."
          git tag --sort=-v:refname | grep '^v1\.0\.[0-9]\+-vscode' || echo "No matching tags found"

          LAST_1_0_TAG=$(git tag --sort=-v:refname | grep '^v1\.0\.[0-9]\+-vscode' | head -n1)
          echo "Selected v1.0.y tag: $LAST_1_0_TAG"
          if [ -z "$LAST_1_0_TAG" ]; then
            echo "::error::No v1.0.y-vscode tag found"
            exit 1
          fi

          # Extract the y number and increment it
          Y_NUMBER=$(echo $LAST_1_0_TAG | sed 's/v1\.0\.\([0-9]\+\)-vscode/\1/')
          NEXT_Y=$((Y_NUMBER + 1))
          NEW_BRANCH="v1.0.${NEXT_Y}-vscode"
          NEW_VERSION="1.0.${NEXT_Y}"
          echo "Current Y number: $Y_NUMBER"
          echo "Next Y number: $NEXT_Y"
          echo "New branch name: $NEW_BRANCH"
          echo "New version: $NEW_VERSION"

          # Create new branch from the v1.1.x tag
          echo "Creating new branch from $LAST_1_1_TAG..."
          git checkout $LAST_1_1_TAG
          git checkout -b $NEW_BRANCH

          # Update the version in package.json
          echo "Current package.json version:"
          cat extensions/vscode/package.json | grep version

          echo "Updating version in package.json..."
          jq ".version = \"$NEW_VERSION\"" extensions/vscode/package.json > temp.json && mv temp.json extensions/vscode/package.json

          echo "New package.json version:"
          cat extensions/vscode/package.json | grep version

          # Configure git
          echo "Configuring git..."
          git config user.name "GitHub Actions Bot"
          git config user.email "actions@github.com"

          # Commit and push changes
          echo "Committing changes..."
          git add extensions/vscode/package.json
          git commit -m "Bump VS Code extension to ${NEW_VERSION}"

          echo "Pushing branch to origin..."
          git push origin $NEW_BRANCH

          # Add release creation
          echo "Creating draft release..."
          gh release create "${NEW_BRANCH}" \
            --title "${NEW_BRANCH}" \
            --generate-notes \
            --draft \
            --latest \
            --notes-start-tag "${LAST_1_0_TAG}"

          echo "Version bump process completed successfully!"

      - name: Check for errors
        if: failure()
        run: |
          echo "::error::Failed to process version tags and create new branch"
          echo "Last few lines of git log:"
          git log -n 5 --oneline
          echo "Current git status:"
          git status
          echo "Current branches:"
          git branch -a