Skip to content

Commit

Permalink
ci: Add tests for new update-issues tool (#3900)
Browse files Browse the repository at this point in the history
This ports over internal tests suggested in #3889.
  • Loading branch information
joeyparrish committed Jan 25, 2022
1 parent 69b2769 commit d1f00b8
Show file tree
Hide file tree
Showing 8 changed files with 967 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/README.md
Expand Up @@ -5,3 +5,5 @@
Lints the player, and builds and tests each combination of OS and browser.
- 'update_issues.yaml':
Updates GitHub issues on a timer.
- 'test_update_issues.yaml':
Runs tests on the update-issues tool when it changes.
28 changes: 28 additions & 0 deletions .github/workflows/test_update_issues.yaml
@@ -0,0 +1,28 @@
name: Test Update Issues Tool

on:
pull_request: # Trigger for pull requests.
types: [opened, synchronize, reopened]
paths:
.github/workflows/tools/update-issues/**
workflow_dispatch: # Allows for manual triggering.
inputs:
ref:
description: "The ref to build and test."
required: False

jobs:
test:
name: Test Update Issues Tool
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.event.inputs.ref || github.ref }}

- name: Test
run: |
cd .github/workflows/tools/update-issues
npm install
npm test
75 changes: 55 additions & 20 deletions .github/workflows/tools/update-issues/main.js
Expand Up @@ -12,14 +12,19 @@ const core = require('@actions/core');
const { Issue, Milestone } = require('./issues.js');

const TYPE_ACCESSIBILITY = 'type: accessibility';
const TYPE_ANNOUNCEMENT = 'type: announcement';
const TYPE_BUG = 'type: bug';
const TYPE_CI = 'type: CI';
const TYPE_CODE_HEALTH = 'type: code health';
const TYPE_DOCS = 'type: docs';
const TYPE_ENHANCEMENT = 'type: enhancement';
const TYPE_PERFORMANCE = 'type: performance';
const TYPE_PROCESS = 'type: process';
const TYPE_QUESTION = 'type: question';

const PRIORITY_P0 = 'priority: P0';
const PRIORITY_P1 = 'priority: P1';
const PRIORITY_P2 = 'priority: P2';
const PRIORITY_P3 = 'priority: P3';
const PRIORITY_P4 = 'priority: P4';

Expand Down Expand Up @@ -196,24 +201,9 @@ const ALL_ISSUE_TASKS = [
maintainMilestones,
];

async function main() {
const milestones = await Milestone.getAll();
const issues = await Issue.getAll();

const backlog = milestones.find(m => m.isBacklog());
if (!backlog) {
core.error('No backlog milestone found!');
process.exit(1);
}
async function processIssues(issues, nextMilestone, backlog) {
let success = true;

milestones.sort(Milestone.compare);
const nextMilestone = milestones[0];
if (nextMilestone.version == null) {
core.error('No version milestone found!');
process.exit(1);
}

let failed = false;
for (const issue of issues) {
if (issue.hasLabel(FLAG_IGNORE)) {
core.info(`Ignoring issue #${issue.number}`);
Expand All @@ -231,14 +221,59 @@ async function main() {
core.error(
`Failed to process issue #${issue.number} in task ${task.name}: ` +
`${error}\n${error.stack}`);
failed = true;
success = false;
}
}
}

if (failed) {
return success;
}

async function main() {
const milestones = await Milestone.getAll();
const issues = await Issue.getAll();

const backlog = milestones.find(m => m.isBacklog());
if (!backlog) {
core.error('No backlog milestone found!');
process.exit(1);
}

milestones.sort(Milestone.compare);
const nextMilestone = milestones[0];
if (nextMilestone.version == null) {
core.error('No version milestone found!');
process.exit(1);
}

const success = await processIssues(issues, nextMilestone, backlog);
if (!success) {
process.exit(1);
}
}

main();
// If this file is the entrypoint, run main. Otherwise, export certain pieces
// to the tests.
if (require.main == module) {
main();
} else {
module.exports = {
processIssues,
TYPE_ACCESSIBILITY,
TYPE_ANNOUNCEMENT,
TYPE_BUG,
TYPE_CODE_HEALTH,
TYPE_DOCS,
TYPE_ENHANCEMENT,
TYPE_PROCESS,
TYPE_QUESTION,
PRIORITY_P0,
PRIORITY_P1,
PRIORITY_P2,
PRIORITY_P3,
PRIORITY_P4,
STATUS_ARCHIVED,
STATUS_WAITING,
FLAG_IGNORE,
};
}
129 changes: 129 additions & 0 deletions .github/workflows/tools/update-issues/mocks.js
@@ -0,0 +1,129 @@
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

/**
* @fileoverview Mocks for the classes in issues.js
*/

function randomInt() {
return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
}
let nextIssueNumber = 1;

class MockGitHubObject {
constructor(subclassDefaults, params) {
const defaults = {
id: randomInt(),
ageInDays: 0,
closedDays: 0,

...subclassDefaults,
};

const mergedParams = {
...defaults,
...params,
};

for (const k in mergedParams) {
this[k] = mergedParams[k];
}
}

toString() {
return JSON.stringify(this, null, ' ');
}
}

class MockMilestone extends MockGitHubObject {
constructor(params) {
const defaults = {
title: 'MockMilestone',
version: null,
closed: false,
isBacklog: () => false,
};

super(defaults, params);
}
}

class MockComment extends MockGitHubObject {
constructor(params) {
const defaults = {
author: 'SomeUser',
body: 'Howdy!',
authorAssociation: 'NONE',
fromTeam: false,
};

super(defaults, params);
}
}

class MockIssue extends MockGitHubObject {
constructor(params) {
const defaults = {
number: nextIssueNumber++,
author: 'SomeUser',
labels: [],
closed: false,
locked: false,
milestone: null,
comments: [],
};

super(defaults, params);

this.getLabelAgeInDays =
jasmine.createSpy('getLabelAgeInDays')
.and.returnValue(params.labelAgeInDays || 0);
this.addLabel = jasmine.createSpy('addLabel').and.callFake((name) => {
console.log(`Adding label ${name}`);
});
this.removeLabel = jasmine.createSpy('removeLabel').and.callFake((name) => {
console.log(`Removing label ${name}`);
});
this.lock = jasmine.createSpy('lock').and.callFake(() => {
console.log('Locking');
});
this.unlock = jasmine.createSpy('unlock').and.callFake(() => {
console.log('Unlocking');
});
this.close = jasmine.createSpy('close').and.callFake(() => {
console.log('Closing');
});
this.reopen = jasmine.createSpy('reopen').and.callFake(() => {
console.log('Reopening');
});
this.setMilestone =
jasmine.createSpy('setMilestone').and.callFake((milestone) => {
console.log(`Setting milestone to "${milestone.title}"`);
});
this.removeMilestone =
jasmine.createSpy('removeMilestone').and.callFake(() => {
console.log('Removing milestone.');
});
this.postComment = jasmine.createSpy('postComment').and.callFake((body) => {
console.log(`Posting comment: ${body}`);
});
this.loadComments = jasmine.createSpy('loadComments');
}

hasLabel(name) {
return this.labels.includes(name);
}

hasAnyLabel(names) {
return this.labels.some(l => names.includes(l));
}
}

module.exports = {
MockMilestone,
MockComment,
MockIssue,
};

0 comments on commit d1f00b8

Please sign in to comment.