Skip to content
Latchkey

Auto-close old version reports workflow (jo-inc/camofox-browser)

The Auto-close old version reports workflow from jo-inc/camofox-browser, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get job timeouts, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: jo-inc/camofox-browser.github/workflows/auto-close-old-reports.ymlLicense MITView source

What it does

This is the Auto-close old version reports workflow from the jo-inc/camofox-browser repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Auto-close old version reports

on:
  issues:
    types: [opened]

jobs:
  check-version:
    if: contains(join(github.event.issue.labels.*.name, ','), 'auto-report')
    runs-on: ubuntu-latest
    permissions:
      issues: write
    steps:
      - name: Check reporter version
        uses: actions/github-script@v7
        with:
          script: |
            const MIN_VERSION = [1, 7, 4];
            const body = context.payload.issue.body || '';

            // Parse "- **version:** X.Y.Z" from issue body
            const match = body.match(/\*\*[Vv]ersion:\*\*\s*v?(\d+\.\d+\.\d+)/);
            if (!match) {
              console.log('No version found in issue body, closing.');
            } else {
              const parts = match[1].split('.').map(Number);
              let dominated = false;
              for (let i = 0; i < MIN_VERSION.length; i++) {
                if ((parts[i] || 0) > MIN_VERSION[i]) { dominated = false; break; }
                if ((parts[i] || 0) < MIN_VERSION[i]) { dominated = true; break; }
              }
              if (!dominated) {
                console.log(`Version ${match[1]} meets minimum ${MIN_VERSION.join('.')}.`);

                const labels = context.payload.issue.labels.map(l => l.name);

                // Auto-close likely-sleep issues (CPU ratio near zero = OS suspend, not real stall)
                if (labels.includes('likely-sleep')) {
                  console.log('likely-sleep label detected, closing.');
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.issue.number,
                    body: 'Closing - classified as OS sleep/suspend (CPU/wall ratio near zero).',
                  });
                  await github.rest.issues.update({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.issue.number,
                    state: 'closed',
                    state_reason: 'not_planned',
                  });
                  return;
                }

                // Auto-close stalls with no active tabs (no user work affected)
                if (labels.includes('stuck')) {
                  const tabMatch = body.match(/\*\*active tabs:\*\*\s*(\d+)/);
                  if (tabMatch && parseInt(tabMatch[1], 10) === 0) {
                    console.log('Stall with 0 active tabs, closing.');
                    await github.rest.issues.createComment({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      body: 'Closing - event loop stall with no active tabs (no user work affected). If you hit this during active browsing, please re-open.',
                    });
                    await github.rest.issues.update({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      state: 'closed',
                      state_reason: 'not_planned',
                    });
                    return;
                  }
                }

                // Auto-close memory leaks with 0 sessions + 0 tabs (self-healing restart handles these)
                if (labels.includes('memory-leak')) {
                  const ctxMatch = body.match(/\*\*browser contexts:\*\*\s*(\d+)/);
                  const tabMatch = body.match(/\*\*active tabs:\*\*\s*(\d+)/);
                  if (ctxMatch && tabMatch &&
                      parseInt(ctxMatch[1], 10) === 0 && parseInt(tabMatch[1], 10) === 0) {
                    console.log('Memory leak with 0 contexts + 0 tabs, closing (self-healing).');
                    await github.rest.issues.createComment({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      body: 'Closing - native memory growth detected with no active sessions. The memory pressure restart mechanism automatically reclaims this when idle. This is expected Firefox/Playwright behavior (jemalloc fragmentation, CDP buffers). If you experience OOM crashes during active use, please re-open.',
                    });
                    await github.rest.issues.update({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      state: 'closed',
                      state_reason: 'not_planned',
                    });
                    return;
                  }
                }

                console.log('Keeping open.');
                return;
              }
              console.log(`Version ${match[1]} below minimum ${MIN_VERSION.join('.')}, closing.`);
            }

            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `Closing - reported from v${match ? match[1] : 'unknown'}, minimum supported is v${MIN_VERSION.join('.')}. Please upgrade to get improved crash diagnostics.`,
            });

            await github.rest.issues.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              state: 'closed',
              state_reason: 'not_planned',
            });

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Auto-close old version reports
 
on:
  issues:
    types: [opened]
 
jobs:
  check-version:
    timeout-minutes: 30
    if: contains(join(github.event.issue.labels.*.name, ','), 'auto-report')
    runs-on: latchkey-small
    permissions:
      issues: write
    steps:
      - name: Check reporter version
        uses: actions/github-script@v7
        with:
          script: |
            const MIN_VERSION = [1, 7, 4];
            const body = context.payload.issue.body || '';
 
            // Parse "- **version:** X.Y.Z" from issue body
            const match = body.match(/\*\*[Vv]ersion:\*\*\s*v?(\d+\.\d+\.\d+)/);
            if (!match) {
              console.log('No version found in issue body, closing.');
            } else {
              const parts = match[1].split('.').map(Number);
              let dominated = false;
              for (let i = 0; i < MIN_VERSION.length; i++) {
                if ((parts[i] || 0) > MIN_VERSION[i]) { dominated = false; break; }
                if ((parts[i] || 0) < MIN_VERSION[i]) { dominated = true; break; }
              }
              if (!dominated) {
                console.log(`Version ${match[1]} meets minimum ${MIN_VERSION.join('.')}.`);
 
                const labels = context.payload.issue.labels.map(l => l.name);
 
                // Auto-close likely-sleep issues (CPU ratio near zero = OS suspend, not real stall)
                if (labels.includes('likely-sleep')) {
                  console.log('likely-sleep label detected, closing.');
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.issue.number,
                    body: 'Closing - classified as OS sleep/suspend (CPU/wall ratio near zero).',
                  });
                  await github.rest.issues.update({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.issue.number,
                    state: 'closed',
                    state_reason: 'not_planned',
                  });
                  return;
                }
 
                // Auto-close stalls with no active tabs (no user work affected)
                if (labels.includes('stuck')) {
                  const tabMatch = body.match(/\*\*active tabs:\*\*\s*(\d+)/);
                  if (tabMatch && parseInt(tabMatch[1], 10) === 0) {
                    console.log('Stall with 0 active tabs, closing.');
                    await github.rest.issues.createComment({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      body: 'Closing - event loop stall with no active tabs (no user work affected). If you hit this during active browsing, please re-open.',
                    });
                    await github.rest.issues.update({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      state: 'closed',
                      state_reason: 'not_planned',
                    });
                    return;
                  }
                }
 
                // Auto-close memory leaks with 0 sessions + 0 tabs (self-healing restart handles these)
                if (labels.includes('memory-leak')) {
                  const ctxMatch = body.match(/\*\*browser contexts:\*\*\s*(\d+)/);
                  const tabMatch = body.match(/\*\*active tabs:\*\*\s*(\d+)/);
                  if (ctxMatch && tabMatch &&
                      parseInt(ctxMatch[1], 10) === 0 && parseInt(tabMatch[1], 10) === 0) {
                    console.log('Memory leak with 0 contexts + 0 tabs, closing (self-healing).');
                    await github.rest.issues.createComment({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      body: 'Closing - native memory growth detected with no active sessions. The memory pressure restart mechanism automatically reclaims this when idle. This is expected Firefox/Playwright behavior (jemalloc fragmentation, CDP buffers). If you experience OOM crashes during active use, please re-open.',
                    });
                    await github.rest.issues.update({
                      owner: context.repo.owner,
                      repo: context.repo.repo,
                      issue_number: context.issue.number,
                      state: 'closed',
                      state_reason: 'not_planned',
                    });
                    return;
                  }
                }
 
                console.log('Keeping open.');
                return;
              }
              console.log(`Version ${match[1]} below minimum ${MIN_VERSION.join('.')}, closing.`);
            }
 
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `Closing - reported from v${match ? match[1] : 'unknown'}, minimum supported is v${MIN_VERSION.join('.')}. Please upgrade to get improved crash diagnostics.`,
            });
 
            await github.rest.issues.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              state: 'closed',
              state_reason: 'not_planned',
            });
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow