Merge branch 'main' into main

This commit is contained in:
Josh Dales
2023-01-11 17:02:22 -05:00
committed by GitHub
39 changed files with 3087 additions and 3654 deletions

35
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,35 @@
---
name: Bug report
about: Create a bug report
title: ''
labels: bug, needs triage
assignees: ''
---
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
<!--- Before opening up a new bug report, please make sure to check for similar existing issues -->
**Description:**
A clear and concise description of what the bug is.
**Action version:**
Specify the action version
**Platform:**
- [ ] Ubuntu
- [ ] macOS
- [ ] Windows
**Runner type:**
- [ ] Hosted
- [ ] Self-hosted
**Repro steps:**
A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link.
**Expected behavior:**
A description of what you expected to happen.
**Actual behavior:**
A description of what is actually happening.

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -0,0 +1,18 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request, needs triage
assignees: ''
---
<!--- Please direct any generic questions related to actions to our support community forum at https://github.community/c/code-to-cloud/github-actions/41 --->
<!--- Before opening up a new feature request, please make sure to check for similar existing issues and pull requests -->
**Description:**
Describe your proposal.
**Justification:**
Justification or a use case for your proposal.
**Are you willing to submit a PR?**
<!--- We accept contributions! -->

9
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,9 @@
**Description:**
Describe your changes.
**Related issue:**
Add link to the related issue.
**Check list:**
- [ ] Mark if documentation changes are required.
- [ ] Mark if tests were added or updated to cover the changes.

17
.github/workflows/basic-validation.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: Basic validation
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- main
- releases/*
paths-ignore:
- '**.md'
jobs:
call-basic-validation:
name: Basic validation
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main

View File

@@ -1,28 +0,0 @@
name: Build & Test
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- main
- releases/*
paths-ignore:
- '**.md'
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- name: Setup node 16
uses: actions/setup-node@v2
with:
node-version: 16.x
- run: npm install
- run: npm run build
- run: npm test

17
.github/workflows/check-dist.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: Check dist/
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
jobs:
call-check-dist:
name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main

14
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
name: CodeQL analysis
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 3 * * 0'
jobs:
call-codeQL-analysis:
name: CodeQL analysis
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main

15
.github/workflows/licensed.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: Licensed
on:
push:
branches:
- main
pull_request:
branches:
- main
workflow_dispatch:
jobs:
call-licensed:
name: Licensed
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main

View File

@@ -0,0 +1,28 @@
name: Release new action version
on:
release:
types: [released]
workflow_dispatch:
inputs:
TAG_NAME:
description: 'Tag name that the major tag will point to'
required: true
env:
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
permissions:
contents: write
jobs:
update_tag:
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
environment:
name: releaseNewActionVersion
runs-on: ubuntu-latest
steps:
- name: Update the ${{ env.TAG_NAME }} tag
uses: actions/publish-action@v0.2.1
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

View File

@@ -1,50 +0,0 @@
name: Licenses
on:
push:
branches: [main]
paths: [package.json, package-lock.json]
pull_request:
branches: [main]
paths: [package.json, package-lock.json]
workflow_dispatch:
jobs:
# Updates our cache of license files in response to changes to our dependencies
# declared in package-lock.json. Automatically commits the changes and pushes
# them to your branch. NB `check_license_status` should always run *after* this
#
# see https://github.com/actions/labeler/pull/155 for more context
update_licenses:
runs-on: ubuntu-latest
name: Update Licenses
steps:
- uses: actions/checkout@v1
- uses: jonabc/setup-licensed@v1
with:
version: '3.x'
github_token: ${{ secrets.GITHUB_TOKEN }}
- run: npm install --production
- uses: jonabc/licensed-ci@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# Fails if any of our dependencies have licenses that our incompatible with our
# requirements (see .licensed.yml) OR if any of our dependencies have been
# upgraded to a new version without us having updated their corresponding
# license metadata file in .licenses/
#
# see https://github.com/actions/labeler/pull/91 for more context
check_licenses:
needs: update_licenses
if: always() # always run after we update the license cache. if it failed, we will probably just fail as well
runs-on: ubuntu-latest
name: Check Licenses
steps:
- uses: actions/checkout@v2
- uses: jonabc/setup-licensed@v1.0.2
with:
version: '3.x'
github_token: ${{ secrets.GITHUB_TOKEN }}
- run: npm install
- run: licensed status

View File

@@ -1,6 +1,6 @@
--- ---
name: "@actions/core" name: "@actions/core"
version: 1.9.1 version: 1.10.0
type: npm type: npm
summary: Actions core lib summary: Actions core lib
homepage: https://github.com/actions/toolkit/tree/main/packages/core homepage: https://github.com/actions/toolkit/tree/main/packages/core

View File

@@ -1,6 +1,6 @@
--- ---
name: "@actions/github" name: "@actions/github"
version: 5.0.0 version: 5.1.1
type: npm type: npm
summary: Actions github lib summary: Actions github lib
homepage: https://github.com/actions/toolkit/tree/main/packages/github homepage: https://github.com/actions/toolkit/tree/main/packages/github

View File

@@ -1,32 +0,0 @@
---
name: "@actions/http-client"
version: 1.0.11
type: npm
summary: Actions Http Client
homepage: https://github.com/actions/http-client#readme
license: mit
licenses:
- sources: LICENSE
text: |
Actions Http Client for Node.js
Copyright (c) GitHub, Inc.
All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@@ -1,9 +1,9 @@
--- ---
name: "@octokit/auth-token" name: "@octokit/auth-token"
version: 2.4.5 version: 2.5.0
type: npm type: npm
summary: GitHub API token authentication for browsers and Node.js summary: GitHub API token authentication for browsers and Node.js
homepage: https://github.com/octokit/auth-token.js#readme homepage:
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE

View File

@@ -1,6 +1,6 @@
--- ---
name: "@octokit/core" name: "@octokit/core"
version: 3.5.1 version: 3.6.0
type: npm type: npm
summary: Extendable client for GitHub's REST & GraphQL APIs summary: Extendable client for GitHub's REST & GraphQL APIs
homepage: homepage:

View File

@@ -1,6 +1,6 @@
--- ---
name: "@octokit/graphql" name: "@octokit/graphql"
version: 4.6.4 version: 4.8.0
type: npm type: npm
summary: GitHub GraphQL API client for browsers and Node summary: GitHub GraphQL API client for browsers and Node
homepage: homepage:

View File

@@ -1,8 +1,8 @@
--- ---
name: "@octokit/openapi-types" name: "@octokit/openapi-types"
version: 7.3.2 version: 12.11.0
type: npm type: npm
summary: Generated TypeScript definitions based on GitHub's OpenAPI spec summary: Generated TypeScript definitions based on GitHub's OpenAPI spec for api.github.com
homepage: homepage:
license: mit license: mit
licenses: licenses:

View File

@@ -1,6 +1,6 @@
--- ---
name: "@octokit/plugin-paginate-rest" name: "@octokit/plugin-paginate-rest"
version: 2.13.5 version: 2.21.3
type: npm type: npm
summary: Octokit plugin to paginate REST API endpoint responses summary: Octokit plugin to paginate REST API endpoint responses
homepage: homepage:

View File

@@ -1,6 +1,6 @@
--- ---
name: "@octokit/plugin-rest-endpoint-methods" name: "@octokit/plugin-rest-endpoint-methods"
version: 5.3.1 version: 5.16.2
type: npm type: npm
summary: Octokit plugin adding one method for all of api.github.com REST API endpoints summary: Octokit plugin adding one method for all of api.github.com REST API endpoints
homepage: homepage:

View File

@@ -1,9 +1,9 @@
--- ---
name: "@octokit/request" name: "@octokit/request"
version: 5.6.0 version: 5.6.3
type: npm type: npm
summary: "Send parameterized requests to GitHubâ\x80\x99s APIs with sensible defaults summary: Send parameterized requests to GitHub's APIs with sensible defaults in browsers
in browsers and Node" and Node
homepage: homepage:
license: mit license: mit
licenses: licenses:

View File

@@ -1,6 +1,6 @@
--- ---
name: "@octokit/types" name: "@octokit/types"
version: 6.16.4 version: 6.41.0
type: npm type: npm
summary: Shared TypeScript definitions for Octokit projects summary: Shared TypeScript definitions for Octokit projects
homepage: homepage:

View File

@@ -1,6 +1,6 @@
--- ---
name: balanced-match name: balanced-match
version: 1.0.0 version: 1.0.2
type: npm type: npm
summary: Match balanced character pairs, like "{" and "}" summary: Match balanced character pairs, like "{" and "}"
homepage: https://github.com/juliangruber/balanced-match homepage: https://github.com/juliangruber/balanced-match

View File

@@ -1,6 +1,6 @@
--- ---
name: before-after-hook name: before-after-hook
version: 2.2.2 version: 2.2.3
type: npm type: npm
summary: asynchronous before/error/after hooks for internal functionality summary: asynchronous before/error/after hooks for internal functionality
homepage: homepage:

View File

@@ -1,6 +1,6 @@
--- ---
name: brace-expansion name: brace-expansion
version: 1.1.11 version: 2.0.1
type: npm type: npm
summary: Brace expansion as known from sh/bash summary: Brace expansion as known from sh/bash
homepage: https://github.com/juliangruber/brace-expansion homepage: https://github.com/juliangruber/brace-expansion

View File

@@ -1,31 +0,0 @@
---
name: concat-map
version: 0.0.1
type: npm
summary: concatenative mapdashery
homepage:
license: other
licenses:
- sources: LICENSE
text: |
This software is released under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: README.markdown
text: MIT
notices: []

View File

@@ -1,6 +1,6 @@
--- ---
name: minimatch name: minimatch
version: 3.0.4 version: 5.1.2
type: npm type: npm
summary: a glob matcher in javascript summary: a glob matcher in javascript
homepage: homepage:
@@ -10,7 +10,7 @@ licenses:
text: | text: |
The ISC License The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors Copyright (c) 2011-2022 Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above

12
.prettierrc.json Normal file
View File

@@ -0,0 +1,12 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid",
"parser": "typescript",
"endOfLine": "auto"
}

View File

@@ -1 +1 @@
* @actions/actions-runtime * @actions/setup-actions-team

View File

@@ -1,11 +1,11 @@
# Pull Request Labeler # Pull Request Labeler
<p align="left"> <p align="left">
<a href="https://github.com/actions/labeler/actions?query=workflow%3A%22Build+%26+Test%22++"> <a href="https://github.com/actions/labeler/actions/workflows/basic-validation.yml">
<img alt="build and test status" src="https://github.com/actions/labeler/actions/workflows/build_test.yml/badge.svg"> <img alt="basic validation status" src="https://github.com/actions/labeler/actions/workflows/basic-validation.yml/badge.svg">
</a> </a>
<a href="https://david-dm.org/actions/labeler"> <a href="https://libraries.io/github/actions/labeler">
<img alt="dependencies" src="https://status.david-dm.org/gh/actions/labeler.svg"> <img alt="dependencies" src="https://img.shields.io/librariesio/github/actions/labeler">
</a> </a>
</p> </p>
@@ -59,9 +59,14 @@ label1:
# Add 'label2' to any file changes within 'example2' folder # Add 'label2' to any file changes within 'example2' folder
label2: example2/* label2: example2/*
# Add 'label3' to any PR where the branch name starts with 'example3' # Add label3 to any change to .txt files within the entire repository. Quotation marks are required for the leading asterisk
label3: label3:
- branch: 'example3/**' - '**/*.txt'
# Add 'label4' to any PR where the branch name starts with 'example4'
label4:
- branch: 'example4/**'
``` ```
#### Common Examples #### Common Examples
@@ -72,7 +77,7 @@ repo:
- '*' - '*'
# Add '@domain/core' label to any change within the 'core' package # Add '@domain/core' label to any change within the 'core' package
@domain/core: '@domain/core':
- package/core/* - package/core/*
- package/core/**/* - package/core/**/*

View File

@@ -1,34 +1,34 @@
export const context = { export const context = {
payload: { payload: {
pull_request: { pull_request: {
number: 123, number: 123
}, }
}, },
repo: { repo: {
owner: "monalisa", owner: 'monalisa',
repo: "helloworld", repo: 'helloworld'
}, }
}; };
const mockApi = { const mockApi = {
rest: { rest: {
issues: { issues: {
addLabels: jest.fn(), addLabels: jest.fn(),
removeLabel: jest.fn(), removeLabel: jest.fn()
}, },
pulls: { pulls: {
get: jest.fn().mockResolvedValue({}), get: jest.fn().mockResolvedValue({}),
listFiles: { listFiles: {
endpoint: { endpoint: {
merge: jest.fn().mockReturnValue({}), merge: jest.fn().mockReturnValue({})
}, }
}, }
}, },
repos: { repos: {
getContent: jest.fn(), getContent: jest.fn()
}, }
}, },
paginate: jest.fn(), paginate: jest.fn()
}; };
export const getOctokit = jest.fn().mockImplementation(() => mockApi); export const getOctokit = jest.fn().mockImplementation(() => mockApi);

View File

@@ -1,27 +1,27 @@
import { checkGlobs } from "../src/labeler"; import {checkGlobs} from '../src/labeler';
import * as core from "@actions/core"; import * as core from '@actions/core';
jest.mock("@actions/core"); jest.mock('@actions/core');
beforeAll(() => { beforeAll(() => {
jest.spyOn(core, "getInput").mockImplementation((name, options) => { jest.spyOn(core, 'getInput').mockImplementation((name, options) => {
return jest.requireActual("@actions/core").getInput(name, options); return jest.requireActual('@actions/core').getInput(name, options);
}); });
}); });
const matchConfig = [{ any: ["*.txt"] }]; const matchConfig = [{any: ['*.txt']}];
describe("checkGlobs", () => { describe('checkGlobs', () => {
it("returns true when our pattern does match changed files", () => { it('returns true when our pattern does match changed files', () => {
const changedFiles = ["foo.txt", "bar.txt"]; const changedFiles = ['foo.txt', 'bar.txt'];
const result = checkGlobs(changedFiles, matchConfig); const result = checkGlobs(changedFiles, matchConfig);
expect(result).toBeTruthy(); expect(result).toBeTruthy();
}); });
it("returns false when our pattern does not match changed files", () => { it('returns false when our pattern does not match changed files', () => {
const changedFiles = ["foo.docx"]; const changedFiles = ['foo.docx'];
const result = checkGlobs(changedFiles, matchConfig); const result = checkGlobs(changedFiles, matchConfig);
expect(result).toBeFalsy(); expect(result).toBeFalsy();

View File

@@ -1,46 +1,46 @@
import { run } from "../src/labeler"; import {run} from '../src/labeler';
import * as github from "@actions/github"; import * as github from '@actions/github';
import * as core from "@actions/core"; import * as core from '@actions/core';
const fs = jest.requireActual("fs"); const fs = jest.requireActual('fs');
jest.mock("@actions/core"); jest.mock('@actions/core');
jest.mock("@actions/github"); jest.mock('@actions/github');
const gh = github.getOctokit("_"); const gh = github.getOctokit('_');
const addLabelsMock = jest.spyOn(gh.rest.issues, "addLabels"); const addLabelsMock = jest.spyOn(gh.rest.issues, 'addLabels');
const removeLabelMock = jest.spyOn(gh.rest.issues, "removeLabel"); const removeLabelMock = jest.spyOn(gh.rest.issues, 'removeLabel');
const reposMock = jest.spyOn(gh.rest.repos, "getContent"); const reposMock = jest.spyOn(gh.rest.repos, 'getContent');
const paginateMock = jest.spyOn(gh, "paginate"); const paginateMock = jest.spyOn(gh, 'paginate');
const getPullMock = jest.spyOn(gh.rest.pulls, "get"); const getPullMock = jest.spyOn(gh.rest.pulls, 'get');
const yamlFixtures = { const yamlFixtures = {
"branches.yml": fs.readFileSync("__tests__/fixtures/branches.yml"), 'branches.yml': fs.readFileSync("__tests__/fixtures/branches.yml"),
"only_pdfs.yml": fs.readFileSync("__tests__/fixtures/only_pdfs.yml"), 'only_pdfs.yml': fs.readFileSync("__tests__/fixtures/only_pdfs.yml"),
}; };
afterAll(() => jest.restoreAllMocks()); afterAll(() => jest.restoreAllMocks());
describe("run", () => { describe('run', () => {
it("adds labels to PRs that match our glob patterns", async () => { it('adds labels to PRs that match our glob patterns', async () => {
usingLabelerConfigYaml("only_pdfs.yml"); usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles("foo.pdf"); mockGitHubResponseChangedFiles('foo.pdf');
await run(); await run();
expect(removeLabelMock).toHaveBeenCalledTimes(0); expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(addLabelsMock).toHaveBeenCalledTimes(1); expect(addLabelsMock).toHaveBeenCalledTimes(1);
expect(addLabelsMock).toHaveBeenCalledWith({ expect(addLabelsMock).toHaveBeenCalledWith({
owner: "monalisa", owner: 'monalisa',
repo: "helloworld", repo: 'helloworld',
issue_number: 123, issue_number: 123,
labels: ["touched-a-pdf-file"], labels: ['touched-a-pdf-file']
}); });
}); });
it("does not add labels to PRs that do not match our glob patterns", async () => { it('does not add labels to PRs that do not match our glob patterns', async () => {
usingLabelerConfigYaml("only_pdfs.yml"); usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles("foo.txt"); mockGitHubResponseChangedFiles('foo.txt');
await run(); await run();
@@ -48,23 +48,23 @@ describe("run", () => {
expect(addLabelsMock).toHaveBeenCalledTimes(0); expect(addLabelsMock).toHaveBeenCalledTimes(0);
}); });
it("(with sync-labels: true) it deletes preexisting PR labels that no longer match the glob pattern", async () => { it('(with sync-labels: true) it deletes preexisting PR labels that no longer match the glob pattern', async () => {
let mockInput = { let mockInput = {
"repo-token": "foo", 'repo-token': 'foo',
"configuration-path": "bar", 'configuration-path': 'bar',
"sync-labels": true, 'sync-labels': true
}; };
jest jest
.spyOn(core, "getInput") .spyOn(core, 'getInput')
.mockImplementation((name: string, ...opts) => mockInput[name]); .mockImplementation((name: string, ...opts) => mockInput[name]);
usingLabelerConfigYaml("only_pdfs.yml"); usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles("foo.txt"); mockGitHubResponseChangedFiles('foo.txt');
getPullMock.mockResolvedValue(<any>{ getPullMock.mockResolvedValue(<any>{
data: { data: {
labels: [{ name: "touched-a-pdf-file" }], labels: [{name: 'touched-a-pdf-file'}]
}, }
}); });
await run(); await run();
@@ -72,30 +72,30 @@ describe("run", () => {
expect(addLabelsMock).toHaveBeenCalledTimes(0); expect(addLabelsMock).toHaveBeenCalledTimes(0);
expect(removeLabelMock).toHaveBeenCalledTimes(1); expect(removeLabelMock).toHaveBeenCalledTimes(1);
expect(removeLabelMock).toHaveBeenCalledWith({ expect(removeLabelMock).toHaveBeenCalledWith({
owner: "monalisa", owner: 'monalisa',
repo: "helloworld", repo: 'helloworld',
issue_number: 123, issue_number: 123,
name: "touched-a-pdf-file", name: 'touched-a-pdf-file'
}); });
}); });
it("(with sync-labels: false) it issues no delete calls even when there are preexisting PR labels that no longer match the glob pattern", async () => { it('(with sync-labels: false) it issues no delete calls even when there are preexisting PR labels that no longer match the glob pattern', async () => {
let mockInput = { let mockInput = {
"repo-token": "foo", 'repo-token': 'foo',
"configuration-path": "bar", 'configuration-path': 'bar',
"sync-labels": false, 'sync-labels': false
}; };
jest jest
.spyOn(core, "getInput") .spyOn(core, 'getInput')
.mockImplementation((name: string, ...opts) => mockInput[name]); .mockImplementation((name: string, ...opts) => mockInput[name]);
usingLabelerConfigYaml("only_pdfs.yml"); usingLabelerConfigYaml('only_pdfs.yml');
mockGitHubResponseChangedFiles("foo.txt"); mockGitHubResponseChangedFiles('foo.txt');
getPullMock.mockResolvedValue(<any>{ getPullMock.mockResolvedValue(<any>{
data: { data: {
labels: [{ name: "touched-a-pdf-file" }], labels: [{name: 'touched-a-pdf-file'}]
}, }
}); });
await run(); await run();
@@ -165,11 +165,11 @@ describe("run", () => {
function usingLabelerConfigYaml(fixtureName: keyof typeof yamlFixtures): void { function usingLabelerConfigYaml(fixtureName: keyof typeof yamlFixtures): void {
reposMock.mockResolvedValue(<any>{ reposMock.mockResolvedValue(<any>{
data: { content: yamlFixtures[fixtureName], encoding: "utf8" }, data: {content: yamlFixtures[fixtureName], encoding: 'utf8'}
}); });
} }
function mockGitHubResponseChangedFiles(...files: string[]): void { function mockGitHubResponseChangedFiles(...files: string[]): void {
const returnValue = files.map((f) => ({ filename: f })); const returnValue = files.map(f => ({filename: f}));
paginateMock.mockReturnValue(<any>returnValue); paginateMock.mockReturnValue(<any>returnValue);
} }

3792
dist/index.js vendored

File diff suppressed because one or more lines are too long

2374
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,8 +5,9 @@
"main": "lib/main.js", "main": "lib/main.js",
"scripts": { "scripts": {
"build": "tsc && ncc build lib/main.js", "build": "tsc && ncc build lib/main.js",
"format": "prettier --write \"**/*.ts\"", "format": "prettier --write **/*.ts",
"format-check": "prettier --check \"**/*.ts\"", "format-check": "prettier --check **/*.ts",
"lint": "echo \"Fake command that does nothing. It is used in reusable workflows\"",
"test": "jest" "test": "jest"
}, },
"repository": { "repository": {
@@ -22,20 +23,20 @@
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.9.1", "@actions/core": "^1.10.0",
"@actions/github": "^5.0.0", "@actions/github": "^5.1.1",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"minimatch": "^3.0.4" "minimatch": "^5.1.2"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^27.4.1", "@types/jest": "^27.4.1",
"@types/node": "^16.11.7", "@types/node": "^16.11.7",
"@types/minimatch": "^3.0.5", "@types/minimatch": "^5.1.2",
"@types/js-yaml": "^4.0.5", "@types/js-yaml": "^4.0.5",
"@vercel/ncc": "^0.34.0", "@vercel/ncc": "^0.36.0",
"jest": "^27.5.1", "jest": "^27.5.1",
"prettier": "^2.6.2", "prettier": "^2.8.1",
"ts-jest": "^27.1.3", "ts-jest": "^27.1.3",
"typescript": "^4.6.3" "typescript": "^4.9.4"
} }
} }

View File

@@ -1,7 +1,7 @@
import * as core from "@actions/core"; import * as core from '@actions/core';
import * as github from "@actions/github"; import * as github from '@actions/github';
import * as yaml from "js-yaml"; import * as yaml from 'js-yaml';
import { Minimatch, IMinimatch } from "minimatch"; import {Minimatch, IMinimatch} from 'minimatch';
interface MatchConfig { interface MatchConfig {
all?: string[]; all?: string[];
@@ -14,22 +14,22 @@ type ClientType = ReturnType<typeof github.getOctokit>;
export async function run() { export async function run() {
try { try {
const token = core.getInput("repo-token", { required: true }); const token = core.getInput('repo-token', {required: true});
const configPath = core.getInput("configuration-path", { required: true }); const configPath = core.getInput('configuration-path', {required: true});
const syncLabels = !!core.getInput("sync-labels", { required: false }); const syncLabels = !!core.getInput('sync-labels', {required: false});
const prNumber = getPrNumber(); const prNumber = getPrNumber();
if (!prNumber) { if (!prNumber) {
console.log("Could not get pull request number from context, exiting"); console.log('Could not get pull request number from context, exiting');
return; return;
} }
const client: ClientType = github.getOctokit(token); const client: ClientType = github.getOctokit(token);
const { data: pullRequest } = await client.rest.pulls.get({ const {data: pullRequest} = await client.rest.pulls.get({
owner: github.context.repo.owner, owner: github.context.repo.owner,
repo: github.context.repo.repo, repo: github.context.repo.repo,
pull_number: prNumber, pull_number: prNumber
}); });
core.debug(`fetching changed files for pr #${prNumber}`); core.debug(`fetching changed files for pr #${prNumber}`);
@@ -45,7 +45,7 @@ export async function run() {
core.debug(`processing ${label}`); core.debug(`processing ${label}`);
if (checkGlobs(changedFiles, globs)) { if (checkGlobs(changedFiles, globs)) {
labels.push(label); labels.push(label);
} else if (pullRequest.labels.find((l) => l.name === label)) { } else if (pullRequest.labels.find(l => l.name === label)) {
labelsToRemove.push(label); labelsToRemove.push(label);
} }
} }
@@ -88,15 +88,15 @@ async function getChangedFiles(
const listFilesOptions = client.rest.pulls.listFiles.endpoint.merge({ const listFilesOptions = client.rest.pulls.listFiles.endpoint.merge({
owner: github.context.repo.owner, owner: github.context.repo.owner,
repo: github.context.repo.repo, repo: github.context.repo.repo,
pull_number: prNumber, pull_number: prNumber
}); });
const listFilesResponse = await client.paginate(listFilesOptions); const listFilesResponse = await client.paginate(listFilesOptions);
const changedFiles = listFilesResponse.map((f: any) => f.filename); const changedFiles = listFilesResponse.map((f: any) => f.filename);
core.debug("found changed files:"); core.debug('found changed files:');
for (const file of changedFiles) { for (const file of changedFiles) {
core.debug(" " + file); core.debug(' ' + file);
} }
return changedFiles; return changedFiles;
@@ -126,7 +126,7 @@ async function fetchContent(
owner: github.context.repo.owner, owner: github.context.repo.owner,
repo: github.context.repo.repo, repo: github.context.repo.repo,
path: repoPath, path: repoPath,
ref: github.context.sha, ref: github.context.sha
}); });
return Buffer.from(response.data.content, response.data.encoding).toString(); return Buffer.from(response.data.content, response.data.encoding).toString();
@@ -137,7 +137,7 @@ function getLabelGlobMapFromObject(
): Map<string, StringOrMatchConfig[]> { ): Map<string, StringOrMatchConfig[]> {
const labelGlobs: Map<string, StringOrMatchConfig[]> = new Map(); const labelGlobs: Map<string, StringOrMatchConfig[]> = new Map();
for (const label in configObject) { for (const label in configObject) {
if (typeof configObject[label] === "string") { if (typeof configObject[label] === 'string') {
labelGlobs.set(label, [configObject[label]]); labelGlobs.set(label, [configObject[label]]);
} else if (configObject[label] instanceof Array) { } else if (configObject[label] instanceof Array) {
labelGlobs.set(label, configObject[label]); labelGlobs.set(label, configObject[label]);
@@ -152,9 +152,9 @@ function getLabelGlobMapFromObject(
} }
function toMatchConfig(config: StringOrMatchConfig): MatchConfig { function toMatchConfig(config: StringOrMatchConfig): MatchConfig {
if (typeof config === "string") { if (typeof config === 'string') {
return { return {
any: [config], any: [config]
}; };
} }
@@ -162,7 +162,7 @@ function toMatchConfig(config: StringOrMatchConfig): MatchConfig {
} }
function printPattern(matcher: IMinimatch): string { function printPattern(matcher: IMinimatch): string {
return (matcher.negate ? "!" : "") + matcher.pattern; return (matcher.negate ? '!' : '') + matcher.pattern;
} }
export function checkGlobs( export function checkGlobs(
@@ -195,7 +195,7 @@ function isMatch(changedFile: string, matchers: IMinimatch[]): boolean {
// equivalent to "Array.some()" but expanded for debugging and clarity // equivalent to "Array.some()" but expanded for debugging and clarity
function checkAny(changedFiles: string[], globs: string[]): boolean { function checkAny(changedFiles: string[], globs: string[]): boolean {
const matchers = globs.map((g) => new Minimatch(g)); const matchers = globs.map(g => new Minimatch(g));
core.debug(` checking "any" patterns`); core.debug(` checking "any" patterns`);
for (const changedFile of changedFiles) { for (const changedFile of changedFiles) {
if (isMatch(changedFile, matchers)) { if (isMatch(changedFile, matchers)) {
@@ -210,7 +210,7 @@ function checkAny(changedFiles: string[], globs: string[]): boolean {
// equivalent to "Array.every()" but expanded for debugging and clarity // equivalent to "Array.every()" but expanded for debugging and clarity
function checkAll(changedFiles: string[], globs: string[]): boolean { function checkAll(changedFiles: string[], globs: string[]): boolean {
const matchers = globs.map((g) => new Minimatch(g)); const matchers = globs.map(g => new Minimatch(g));
core.debug(` checking "all" patterns`); core.debug(` checking "all" patterns`);
for (const changedFile of changedFiles) { for (const changedFile of changedFiles) {
if (!isMatch(changedFile, matchers)) { if (!isMatch(changedFile, matchers)) {
@@ -290,7 +290,7 @@ async function addLabels(
owner: github.context.repo.owner, owner: github.context.repo.owner,
repo: github.context.repo.repo, repo: github.context.repo.repo,
issue_number: prNumber, issue_number: prNumber,
labels: labels, labels: labels
}); });
} }
@@ -300,12 +300,12 @@ async function removeLabels(
labels: string[] labels: string[]
) { ) {
await Promise.all( await Promise.all(
labels.map((label) => labels.map(label =>
client.rest.issues.removeLabel({ client.rest.issues.removeLabel({
owner: github.context.repo.owner, owner: github.context.repo.owner,
repo: github.context.repo.repo, repo: github.context.repo.repo,
issue_number: prNumber, issue_number: prNumber,
name: label, name: label
}) })
) )
); );

View File

@@ -1,3 +1,3 @@
import { run } from "./labeler"; import {run} from './labeler';
run(); run();