Repository: actions/labeler (TypeScript)

Issue:
How to only add label, not remove when PR is opened?
I have a labeler action set up for when PR is opened, using all your default settings. The [labeler YAML](https://github.com/astropy/astropy/blob/master/.github/labeler.yml) is set up as such (relevant parts listed below):

```yaml
Docs:
  - docs/*

coordinates:
  - '**/coordinates/**/*'
```

When astropy/astropy#11023 was opened, the only file changed was `docs/coordinates/apply_space_motion.rst`. By the labeler logic, it should apply `Docs` and `coordinates`.

**However,** the PR author already manually applied `Docs` label at creation time. As a result, the labeler ended up *removing* the `Docs` label. Is this a bug? How do I tell it to simply no-op when a label that should be applied is already there?

![Screenshot 2020-11-10 234620](https://user-images.githubusercontent.com/2090236/98769915-f5cbfc00-23ae-11eb-9c54-7451597de23f.jpg)

Hope you can help and thanks for such a useful action!


Discussion:
Strangely enough, accidental removal did not happen for astropy/astropy#11028 when the file changed was only `docs/conf.py` and `Docs` label was also applied manually when PR was opened.

![Screenshot 2020-11-11 101002](https://user-images.githubusercontent.com/2090236/98828449-196e6100-2406-11eb-868b-20ef8d1352d1.jpg)

![Screenshot 2020-11-11 101107](https://user-images.githubusercontent.com/2090236/98828578-3d31a700-2406-11eb-947b-5ed9f45b76fb.jpg)

(The Action ran successfully but it was a no-op, as expected.)
There hasn't been much progress in the conversation, but I also want to solve this problem.
By removing the manually attached tags, the benefits gained by labelar are diminished.
Any news here?
It looks like the problem is https://github.com/actions/labeler/blob/590628261a373c5bb0bbfbb751555f06766aace0/src/labeler.ts#L18
which is not correct because the default value is `"false"`, and `!!"false" == true`.
Confirmed, you can work around this bug by setting
```yaml
sync-labels: ''
```
in your workflow.
> Confirmed, you can work around this bug by setting
> 
> ```yaml
> sync-labels: ''
> ```
> 
> in your workflow.

Thanks for this, can also confirm this works in v4. Any plans to fix this properly in the next version?
This still may happen with v5 action if the labels are added by the user at the time that's very close to the action run:
<img width="416" alt="image" src="https://github.com/user-attachments/assets/e3a86c5a-9a3d-4085-87ba-fd760c27098b">

User added labels at `2024-07-19T15:07:34Z`. Bot added his own at `2024-07-19T15:07:35Z`.

And bot started running at `2024-07-19T15:07:34Z` as per GH action logs. So my guess is that it read labels, then user added his labels, then bot applied the rules and has overridden some of the labels the user has previously added.

WF config:
```
# .github/workflows/auto-labeler.yaml
name: "Pull Request Labeler"
on:
  pull_request_target:
    types: [ opened, reopened, synchronize ]

jobs:
  labeler:
    permissions:
      contents: read
      pull-requests: write
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/labeler@v5
        with:
          sync-labels: false
          dot: true
          configuration-path: .github/labeler.yaml
```

Related rules:
```
"/web":
  - any:
      - changed-files:
          - any-glob-to-any-file:
              - SOME FILES
javascript:
  - any:
      - changed-files:
          - any-glob-to-any-file:
              - src/js/**
```



Patch:
diff --git a/dist/index.js b/dist/index.js
index a841c0863..326115eca 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -49,7 +49,7 @@ function run() {
         try {
             const token = core.getInput('repo-token');
             const configPath = core.getInput('configuration-path', { required: true });
-            const syncLabels = !!core.getInput('sync-labels', { required: false });
+            const syncLabels = core.getBooleanInput('sync-labels');
             const prNumber = getPrNumber();
             if (!prNumber) {
                 core.info('Could not get pull request number from context, exiting');
diff --git a/src/labeler.ts b/src/labeler.ts
index d71880cb7..2300d9b6f 100644
--- a/src/labeler.ts
+++ b/src/labeler.ts
@@ -15,7 +15,7 @@ export async function run() {
   try {
     const token = core.getInput('repo-token');
     const configPath = core.getInput('configuration-path', {required: true});
-    const syncLabels = !!core.getInput('sync-labels', {required: false});
+    const syncLabels = core.getBooleanInput('sync-labels');
 
     const prNumber = getPrNumber();
     if (!prNumber) {


Test patch:
diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts
index ab62eae37..426b1e822 100644
--- a/__tests__/main.test.ts
+++ b/__tests__/main.test.ts
@@ -51,12 +51,17 @@ describe('run', () => {
     const mockInput = {
       'repo-token': 'foo',
       'configuration-path': 'bar',
-      'sync-labels': true
+      'sync-labels': 'true'
     };
 
     jest
       .spyOn(core, 'getInput')
       .mockImplementation((name: string, ...opts) => mockInput[name]);
+    jest
+      .spyOn(core, 'getBooleanInput')
+      .mockImplementation(
+        (name: string, ...opts) => mockInput[name] === 'true'
+      );
 
     usingLabelerConfigYaml('only_pdfs.yml');
     mockGitHubResponseChangedFiles('foo.txt');
@@ -82,12 +87,17 @@ describe('run', () => {
     const mockInput = {
       'repo-token': 'foo',
       'configuration-path': 'bar',
-      'sync-labels': false
+      'sync-labels': 'false'
     };
 
     jest
       .spyOn(core, 'getInput')
       .mockImplementation((name: string, ...opts) => mockInput[name]);
+    jest
+      .spyOn(core, 'getBooleanInput')
+      .mockImplementation(
+        (name: string, ...opts) => mockInput[name] === 'true'
+      );
 
     usingLabelerConfigYaml('only_pdfs.yml');
     mockGitHubResponseChangedFiles('foo.txt');