@@ -3,7 +3,10 @@ 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 { getConfig , NgDevConfig } from '../../../ng-dev/utils/config.js' ;
7+ import { PullRequestConfig } from '../../../ng-dev/pr/config/index.js' ;
68import { ANGULAR_ROBOT , getAuthTokenFor , revokeActiveInstallationToken } from '../../utils.js' ;
9+ import micromatch from 'micromatch' ;
710import { ManagedRepositories } from '../../../ng-dev/pr/common/labels/base.js' ;
811
912/** The type of the response data for a the pull request get method on from octokit. */
@@ -20,7 +23,7 @@ class PullRequestLabeling {
2023 const inst = new this ( git ) ;
2124 await inst . run ( ) ;
2225 } finally {
23- await revokeActiveInstallationToken ( git ) ;
26+ await revokeActiveInstallationToken ( token ) ;
2427 }
2528 } ;
2629
@@ -32,6 +35,10 @@ class PullRequestLabeling {
3235 commits : Commit [ ] = [ ] ;
3336 /** The pull request information from the github API. */
3437 pullRequestMetadata ?: PullRequestGetData ;
38+ /** The configuration for the pull request. */
39+ config ?: NgDevConfig < { pullRequest : PullRequestConfig } > ;
40+ /** The files in the pull request. */
41+ pullRequestFilePaths : string [ ] = [ ] ;
3542
3643 private constructor ( private git : Octokit ) { }
3744
@@ -42,9 +49,31 @@ class PullRequestLabeling {
4249 core . info ( `PR #${ context . issue . number } ` ) ;
4350
4451 await this . commitMessageBasedLabeling ( ) ;
52+ await this . pathBasedLabeling ( ) ;
4553 await this . pullRequestMetadataLabeling ( ) ;
4654 }
4755
56+ /**
57+ * Perform labeling based on the path of the files in the pull request.
58+ */
59+ async pathBasedLabeling ( ) {
60+ const managedLabelByPath = this . config ?. pullRequest ?. managedLabelByPath ;
61+ if ( ! managedLabelByPath ) {
62+ return ;
63+ }
64+
65+ for ( const [ label , paths ] of Object . entries ( managedLabelByPath ) ) {
66+ if (
67+ this . pullRequestFilePaths . length > 0 &&
68+ micromatch ( this . pullRequestFilePaths , paths as string | string [ ] ) . length > 0
69+ ) {
70+ if ( ! this . labels . has ( label ) ) {
71+ await this . addLabel ( label ) ;
72+ }
73+ }
74+ }
75+ }
76+
4877 /**
4978 * Perform labeling based on the commit messages for the pull request.
5079 */
@@ -133,6 +162,37 @@ class PullRequestLabeling {
133162 }
134163 }
135164
165+ /** Load the configuration for the pull request. */
166+ private async loadConfig ( ) : Promise < NgDevConfig < { pullRequest : PullRequestConfig } > | undefined > {
167+ try {
168+ return ( await getConfig ( ) ) as NgDevConfig < { pullRequest : PullRequestConfig } > ;
169+ } catch {
170+ const { owner, repo} = context . issue ;
171+ try {
172+ const { data} = await this . git . repos . getContent ( {
173+ owner,
174+ repo,
175+ path : '.ng-dev/labels.json' ,
176+ } ) ;
177+
178+ if ( 'content' in data && typeof data . content === 'string' ) {
179+ const content = Buffer . from ( data . content , 'base64' ) . toString ( ) ;
180+ const { labels} = JSON . parse ( content ) ;
181+ return {
182+ __isNgDevConfigObject : true ,
183+ pullRequest : {
184+ managedLabelByPath : labels ,
185+ githubApiMerge : false , // Not used in this context
186+ } ,
187+ } as NgDevConfig < { pullRequest : PullRequestConfig } > ;
188+ }
189+ } catch ( e ) {
190+ core . info ( `No .ng-dev/labels.json found.` ) ;
191+ }
192+ }
193+ return undefined ;
194+ }
195+
136196 /** Initialize the current labels and commits for the PR. */
137197 async initialize ( ) {
138198 const { number, owner, repo} = context . issue ;
@@ -159,6 +219,14 @@ class PullRequestLabeling {
159219 await this . git . pulls . get ( { owner, repo, pull_number : number } ) . then ( ( { data} ) => {
160220 this . pullRequestMetadata = data ;
161221 } ) ;
222+
223+ this . config = await this . loadConfig ( ) ;
224+
225+ if ( this . config ?. pullRequest ?. managedLabelByPath ) {
226+ await this . git
227+ . paginate ( this . git . pulls . listFiles , { owner, pull_number : number , repo} )
228+ . then ( ( files ) => this . pullRequestFilePaths . push ( ...files . map ( ( file ) => file . filename ) ) ) ;
229+ }
162230 }
163231}
164232
0 commit comments