Files
fleet/.github/workflows/tag-aging-bugs.yml
T
Victor Lyuboslavsky 9f80b9b07a Bump step-security/harden-runner to a non-vulnerable version (#46783)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #41198 




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated security hardening tools across multiple GitHub Actions
workflows to the latest available version for enhanced CI/CD
infrastructure protection and resilience.
* Enabled additional security validation rules in workflow configuration
to strengthen infrastructure oversight and improve vulnerability
detection capabilities across build and deployment pipelines.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-03 17:38:32 -05:00

190 lines
6.7 KiB
YAML

name: Tag aging bugs
# This action will tag bugs based on their age:
# - Bugs >= 180 days old get tagged with ~old bug (and ~aging bug is removed)
# - Bugs >= 90 days old (but < 180 days) get tagged with ~aging bug
on:
schedule:
# Daily at 8:06am UTC
- cron: "6 8 * * *"
workflow_dispatch: # Manual
inputs:
dry_run:
description: 'Dry run mode (log only, do not modify labels)'
required: false
type: boolean
default: false
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id}}
cancel-in-progress: true
defaults:
run:
# fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
shell: bash
permissions:
contents: read
jobs:
tag-bugs:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Harden Runner
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Tag aging bugs
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const dryRun = ${{ github.event.inputs.dry_run || false }};
console.log(`Dry run mode: ${dryRun}`);
// Calculate date thresholds
const now = new Date();
const oldBugDate = new Date(now);
oldBugDate.setDate(oldBugDate.getDate() - 180);
const agingBugDate = new Date(now);
agingBugDate.setDate(agingBugDate.getDate() - 90);
console.log(`Old bug threshold: ${oldBugDate.toISOString()}`);
console.log(`Aging bug threshold: ${agingBugDate.toISOString()}`);
// Process old bugs (>= 180 days)
console.log('\n=== Processing old bugs (>= 180 days) ===');
let page = 1;
let oldBugsProcessed = 0;
while (true) {
const { data: oldBugs } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'bug',
state: 'open',
per_page: 100,
page: page,
sort: 'created',
direction: 'asc'
});
if (oldBugs.length === 0) break;
for (const issue of oldBugs) {
const createdDate = new Date(issue.created_at);
// Stop if we've passed the old bug threshold
if (createdDate > oldBugDate) {
page = Infinity; // Signal to stop pagination
break;
}
const labels = issue.labels.map(label => label.name);
const hasOldBugLabel = labels.includes('~old bug');
if (!hasOldBugLabel) {
oldBugsProcessed++;
console.log(`Issue #${issue.number}: Created ${createdDate.toISOString()}`);
if (dryRun) {
console.log(` [DRY RUN] Would add ~old bug label`);
if (labels.includes('~aging bug')) {
console.log(` [DRY RUN] Would remove ~aging bug label`);
}
} else {
// Add ~old bug label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: ['~old bug']
});
console.log(` Added ~old bug label`);
// Remove ~aging bug if present
if (labels.includes('~aging bug')) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
name: '~aging bug'
});
console.log(` Removed ~aging bug label`);
}
}
}
}
if (page === Infinity) break;
page++;
}
console.log(`\nProcessed ${oldBugsProcessed} old bugs`);
// Process aging bugs (>= 90 days but < 180 days)
console.log('\n=== Processing aging bugs (>= 90 days) ===');
page = 1;
let agingBugsProcessed = 0;
while (true) {
const { data: agingBugs } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'bug',
state: 'open',
per_page: 100,
page: page,
sort: 'created',
direction: 'asc'
});
if (agingBugs.length === 0) break;
for (const issue of agingBugs) {
const createdDate = new Date(issue.created_at);
// Skip if newer than aging threshold
if (createdDate > agingBugDate) {
page = Infinity; // Signal to stop pagination
break;
}
const labels = issue.labels.map(label => label.name);
const hasAgingBugLabel = labels.includes('~aging bug');
const hasOldBugLabel = labels.includes('~old bug');
// Only tag if it doesn't have either label
// (hasOldBugLabel check handles issues that became old since last run)
if (!hasAgingBugLabel && !hasOldBugLabel) {
agingBugsProcessed++;
console.log(`Issue #${issue.number}: Created ${createdDate.toISOString()}`);
if (dryRun) {
console.log(` [DRY RUN] Would add ~aging bug label`);
} else {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: ['~aging bug']
});
console.log(` Added ~aging bug label`);
}
}
}
if (page === Infinity) break;
page++;
}
console.log(`\nProcessed ${agingBugsProcessed} aging bugs`);
console.log(`\n=== Summary ===`);
console.log(`Total old bugs tagged: ${oldBugsProcessed}`);
console.log(`Total aging bugs tagged: ${agingBugsProcessed}`);