@@ -3,8 +3,11 @@ import {context} from '@actions/github';
33import { Octokit , RestEndpointMethodTypes } from '@octokit/rest' ;
44import { Commit , parseCommitMessage } from '../../../ng-dev/commit-message/parse.js' ;
55import { actionLabels , managedLabels , targetLabels } from '../../../ng-dev/pr/common/labels/index.js' ;
6+ import { assertValidPullRequestConfig , PullRequestConfig } from '../../../ng-dev/pr/config/index.js' ;
67import { ANGULAR_ROBOT , getAuthTokenFor , revokeActiveInstallationToken } from '../../utils.js' ;
78import { ManagedRepositories } from '../../../ng-dev/pr/common/labels/base.js' ;
9+ import { getConfig , NgDevConfig } from '../../../ng-dev/utils/config.js' ;
10+ import micromatch from 'micromatch' ;
811
912/** The type of the response data for a the pull request get method on from octokit. */
1013type PullRequestGetData = RestEndpointMethodTypes [ 'pulls' ] [ 'get' ] [ 'response' ] [ 'data' ] ;
@@ -17,7 +20,9 @@ class PullRequestLabeling {
1720 const token = await getAuthTokenFor ( ANGULAR_ROBOT ) ;
1821 const git = new Octokit ( { auth : token } ) ;
1922 try {
20- const inst = new this ( git ) ;
23+ const config = await getConfig ( ) ;
24+ assertValidPullRequestConfig ( config ) ;
25+ const inst = new this ( git , config ) ;
2126 await inst . run ( ) ;
2227 } finally {
2328 await revokeActiveInstallationToken ( git ) ;
@@ -32,8 +37,13 @@ class PullRequestLabeling {
3237 commits : Commit [ ] = [ ] ;
3338 /** The pull request information from the github API. */
3439 pullRequestMetadata ?: PullRequestGetData ;
40+ /** The files changed in the pull request */
41+ pullRequestFilePaths ?: string [ ] ;
3542
36- private constructor ( private git : Octokit ) { }
43+ private constructor (
44+ private git : Octokit ,
45+ private config : NgDevConfig < { pullRequest : PullRequestConfig } > ,
46+ ) { }
3747
3848 /** Run the action, and revoke the installation token on completion. */
3949 async run ( ) {
@@ -43,6 +53,7 @@ class PullRequestLabeling {
4353
4454 await this . commitMessageBasedLabeling ( ) ;
4555 await this . pullRequestMetadataLabeling ( ) ;
56+ await this . pathBasedLabeling ( ) ;
4657 }
4758
4859 /**
@@ -107,6 +118,27 @@ class PullRequestLabeling {
107118 }
108119 }
109120
121+ /**
122+ * Perform labeling based on the paths of the files in the pull request.
123+ */
124+ async pathBasedLabeling ( ) {
125+ const managedLabelByPath = this . config . pullRequest . managedLabelByPath ;
126+ if ( managedLabelByPath === undefined || this . pullRequestFilePaths === undefined ) {
127+ return ;
128+ }
129+
130+ for ( const [ path , labels ] of Object . entries ( managedLabelByPath ) ) {
131+ const files = micromatch ( this . pullRequestFilePaths , path ) ;
132+ if ( files . length > 0 ) {
133+ for ( const label of labels ) {
134+ if ( ! this . labels . has ( label ) ) {
135+ await this . addLabel ( label ) ;
136+ }
137+ }
138+ }
139+ }
140+ }
141+
110142 /** Remove the provided label to the pull request. */
111143 async removeLabel ( label : string ) {
112144 const { number : issue_number , owner, repo} = context . issue ;
@@ -159,6 +191,13 @@ class PullRequestLabeling {
159191 await this . git . pulls . get ( { owner, repo, pull_number : number } ) . then ( ( { data} ) => {
160192 this . pullRequestMetadata = data ;
161193 } ) ;
194+
195+ if ( this . config . pullRequest . managedLabelByPath ) {
196+ this . pullRequestFilePaths = [ ] ;
197+ await this . git
198+ . paginate ( this . git . pulls . listFiles , { owner, pull_number : number , repo} )
199+ . then ( ( files ) => this . pullRequestFilePaths ?. push ( ...files . map ( ( file ) => file . filename ) ) ) ;
200+ }
162201 }
163202}
164203
0 commit comments