From 44e418ffe7a23d31823fa9b0eb2de22a11d53e4f Mon Sep 17 00:00:00 2001
From: Kir_Antipov <kp.antipov@gmail.com>
Date: Mon, 6 Jun 2022 18:17:42 +0300
Subject: [PATCH] Added `modrinth-featured` input (#9)

---
 README.md                                     | 9 +++++++++
 action.yml                                    | 4 ++++
 src/publishing/mod-publisher.ts               | 4 ++--
 src/publishing/modrinth/modrinth-publisher.ts | 5 ++++-
 test/modrinth-utils.test.ts                   | 8 +++-----
 5 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 05e3cfa..9e71439 100644
--- a/README.md
+++ b/README.md
@@ -90,6 +90,7 @@ jobs:
 |------|-------------|---------------|----------|
 | [modrinth-id](#user-content-modrinth-id) | The ID of the Modrinth project to upload to | A value specified in the config file | `AANobbMI` |
 | [modrinth-token](#user-content-modrinth-token) | A valid token for the Modrinth API | ❌ | `${{ secrets.MODRINTH_TOKEN }}` |
+| [modrinth-featured](#user-content-modrinth-featured) | Indicates whether the version should be featured on Modrinth or not | `true` | `true` <br> `false` |
 | [curseforge-id](#user-content-curseforge-id) | The ID of the CurseForge project to upload to | A value specified in the config file | `394468` |
 | [curseforge-token](#user-content-curseforge-token) | A valid token for the CurseForge API | ❌ | `${{ secrets.CURSEFORGE_TOKEN }}` |
 | [github-tag](#user-content-github-tag) | The tag name of the release to upload assets to | A tag of the release that triggered the action | `mc1.17.1-0.3.2` |
@@ -218,6 +219,14 @@ A valid token for the Modrinth API. It's required if you want to publish your as
 modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
 ```
 
+#### modrinth-featured
+
+Indicates whether the version should be featured on Modrinth or not.
+
+```yaml
+modrinth-featured: true
+```
+
 #### curseforge-id
 
 The ID of the CurseForge project to upload to.
diff --git a/action.yml b/action.yml
index 2f4cc2b..11ce982 100644
--- a/action.yml
+++ b/action.yml
@@ -13,6 +13,10 @@ inputs:
     description: A valid token for the Modrinth API
     required: false
     default: ${undefined}
+  modrinth-featured:
+    description: Indicates whether the version should be featured on Modrinth or not
+    required: false
+    default: ${undefined}
 
   curseforge-id:
     description: The ID of the CurseForge project to upload to
diff --git a/src/publishing/mod-publisher.ts b/src/publishing/mod-publisher.ts
index df0d557..f7b4830 100644
--- a/src/publishing/mod-publisher.ts
+++ b/src/publishing/mod-publisher.ts
@@ -115,8 +115,8 @@ export default abstract class ModPublisher extends Publisher<ModPublisherOptions
             : metadata?.dependencies || [];
         const uniqueDependencies = dependencies.filter((x, i, self) => !x.ignore && self.findIndex(y => y.id === x.id && y.kind === x.kind) === i);
 
-        await this.publishMod(id, token, name, version, versionType, loaders, gameVersions, java, changelog, files, uniqueDependencies);
+        await this.publishMod(id, token, name, version, versionType, loaders, gameVersions, java, changelog, files, uniqueDependencies, <Record<string, unknown>><unknown>options);
     }
 
-    protected abstract publishMod(id: string, token: string, name: string, version: string, versionType: string, loaders: string[], gameVersions: string[], java: string[], changelog: string, files: File[], dependencies: Dependency[]): Promise<void>;
+    protected abstract publishMod(id: string, token: string, name: string, version: string, versionType: string, loaders: string[], gameVersions: string[], java: string[], changelog: string, files: File[], dependencies: Dependency[], options: Record<string, unknown>): Promise<void>;
 }
\ No newline at end of file
diff --git a/src/publishing/modrinth/modrinth-publisher.ts b/src/publishing/modrinth/modrinth-publisher.ts
index 3c00635..75ab175 100644
--- a/src/publishing/modrinth/modrinth-publisher.ts
+++ b/src/publishing/modrinth/modrinth-publisher.ts
@@ -4,6 +4,7 @@ import ModPublisher from "../mod-publisher";
 import PublisherTarget from "../publisher-target";
 import Dependency from "../../metadata/dependency";
 import DependencyKind from "../../metadata/dependency-kind";
+import { mapBooleanInput } from "../../utils/input-utils";
 
 const modrinthDependencyKinds = new Map([
     [DependencyKind.Depends, "required"],
@@ -18,7 +19,8 @@ export default class ModrinthPublisher extends ModPublisher {
         return PublisherTarget.Modrinth;
     }
 
-    protected async publishMod(id: string, token: string, name: string, version: string, channel: string, loaders: string[], gameVersions: string[], _java: string[], changelog: string, files: File[], dependencies: Dependency[]): Promise<void> {
+    protected async publishMod(id: string, token: string, name: string, version: string, channel: string, loaders: string[], gameVersions: string[], _java: string[], changelog: string, files: File[], dependencies: Dependency[], options: Record<string, unknown>): Promise<void> {
+        const featured = mapBooleanInput(options.featured, true);
         const projects = (await Promise.all(dependencies
             .filter((x, _, self) => (x.kind !== DependencyKind.Suggests && x.kind !== DependencyKind.Includes) || !self.find(y => y.id === x.id && y.kind !== DependencyKind.Suggests && y.kind !== DependencyKind.Includes))
             .map(async x => ({
@@ -34,6 +36,7 @@ export default class ModrinthPublisher extends ModPublisher {
             game_versions: gameVersions,
             version_type: channel,
             loaders,
+            featured,
             dependencies: projects
         };
         await createVersion(id, data, files, token);
diff --git a/test/modrinth-utils.test.ts b/test/modrinth-utils.test.ts
index 7d3377f..bc8e896 100644
--- a/test/modrinth-utils.test.ts
+++ b/test/modrinth-utils.test.ts
@@ -1,9 +1,8 @@
-import { jest, describe, test, expect } from "@jest/globals";
+import { describe, test, expect } from "@jest/globals";
 import { getProject } from "../src/utils/modrinth-utils";
 
 describe("getProject", () => {
     test("returned versions have expected ids", async () => {
-        jest.setTimeout(15000);
         const projects = {
             "sodium": "AANobbMI",
             "fabric-api": "P7dR8mSH",
@@ -16,10 +15,9 @@ describe("getProject", () => {
             const project = await getProject(slug);
             expect(project).toHaveProperty("id", id);
         }
-    });
+    }, 15000);
 
     test("the method returns null if project with the given slug does not exist", async () => {
-        jest.setTimeout(15000);
         const nonExistentProjects = [
             "Na-11",
             "api-fabric",
@@ -33,5 +31,5 @@ describe("getProject", () => {
             const project = await getProject(slug);
             expect(project).toBeNull();
         }
-    });
+    }, 15000);
 });