diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 93329f4..2cf3c29 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -111,15 +111,25 @@ jobs: expected-version: "0.3.5" - version-input: ">=0.4.25,<0.5" expected-version: "0.4.30" + - version-input: ">=0.4.25,<0.5" + expected-version: "0.4.25" + resolution-strategy: "lowest" + - version-input: ">=0.1.0,<0.2" + expected-version: "0.1.19" + resolution-strategy: "highest" + - version-input: ">=0.1.0,<0.2" + expected-version: "0.1.0" + resolution-strategy: "lowest" steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - - name: Install version ${{ matrix.input.version-input }} + - name: Install version ${{ matrix.input.version-input }} with strategy ${{ matrix.input.resolution-strategy || 'highest' }} id: setup-uv uses: ./ with: version: ${{ matrix.input.version-input }} + resolution-strategy: ${{ matrix.input.resolution-strategy || 'highest' }} - name: Correct version gets installed run: | if [ "$(uv --version)" != "uv ${{ matrix.input.expected-version }}" ]; then diff --git a/RESOLUTION_STRATEGY_DEMO.md b/RESOLUTION_STRATEGY_DEMO.md deleted file mode 100644 index 7103779..0000000 --- a/RESOLUTION_STRATEGY_DEMO.md +++ /dev/null @@ -1,43 +0,0 @@ -# Resolution Strategy Demo - -This file demonstrates the new `resolution-strategy` input. - -## Default behavior (highest strategy) -```yaml -- name: Install highest compatible uv version - uses: astral-sh/setup-uv@v6 - with: - version: ">=0.4.0" - # resolution-strategy: "highest" is the default -``` - -## Lowest strategy for testing compatibility -```yaml -- name: Install lowest compatible uv version - uses: astral-sh/setup-uv@v6 - with: - version: ">=0.4.0" - resolution-strategy: "lowest" -``` - -## Use case: Testing with matrix of strategies -```yaml -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - resolution-strategy: ["highest", "lowest"] - steps: - - uses: actions/checkout@v5 - - name: Install uv with ${{ matrix.resolution-strategy }} strategy - uses: astral-sh/setup-uv@v6 - with: - version: ">=0.4.0" - resolution-strategy: ${{ matrix.resolution-strategy }} - cache-suffix: ${{ matrix.resolution-strategy }} - - name: Test with strategy - run: | - echo "Testing with $(uv --version)" - uv run --frozen pytest -``` \ No newline at end of file diff --git a/__tests__/download/resolution-strategy.test.ts b/__tests__/download/resolution-strategy.test.ts deleted file mode 100644 index ea11cec..0000000 --- a/__tests__/download/resolution-strategy.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { describe, expect, it } from "@jest/globals"; - -describe("resolution strategy logic", () => { - it("should have correct string values for resolution strategy", () => { - // Test the string literal types are correct - const strategies: Array<"highest" | "lowest"> = ["highest", "lowest"]; - expect(strategies).toHaveLength(2); - expect(strategies).toContain("highest"); - expect(strategies).toContain("lowest"); - }); - - it("should validate resolution strategy values", () => { - const validStrategies = ["highest", "lowest"]; - const invalidStrategies = ["invalid", "HIGHEST", "LOWEST", "middle"]; - - for (const strategy of validStrategies) { - expect(["highest", "lowest"]).toContain(strategy); - } - - for (const strategy of invalidStrategies) { - expect(["highest", "lowest"]).not.toContain(strategy); - } - }); -}); diff --git a/__tests__/integration/resolution-strategy-logic.test.ts b/__tests__/integration/resolution-strategy-logic.test.ts deleted file mode 100644 index 00abe28..0000000 --- a/__tests__/integration/resolution-strategy-logic.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { describe, expect, it } from "@jest/globals"; - -describe("resolution strategy integration test", () => { - it("should choose max satisfying version for highest strategy", () => { - // Test the logic that chooses between max/min satisfying - const versions = ["0.1.0", "0.2.0", "0.3.0"]; - - // Simulate the logic from our implementation - const strategyLogic = (strategy: "highest" | "lowest") => { - // This simulates what semver.minSatisfying and semver.maxSatisfying would return - if (strategy === "lowest") { - return versions.find((v) => v >= "0.1.0"); // First match (lowest) - } else { - return versions.filter((v) => v >= "0.1.0").pop(); // Last match (highest) - } - }; - - expect(strategyLogic("highest")).toBe("0.3.0"); - expect(strategyLogic("lowest")).toBe("0.1.0"); - }); - - it("should validate resolution strategy values correctly", () => { - const getResolutionStrategy = (input: string): "highest" | "lowest" => { - if (input === "lowest") { - return "lowest"; - } - if (input === "highest" || input === "") { - return "highest"; - } - throw new Error( - `Invalid resolution-strategy: ${input}. Must be 'highest' or 'lowest'.`, - ); - }; - - expect(getResolutionStrategy("")).toBe("highest"); - expect(getResolutionStrategy("highest")).toBe("highest"); - expect(getResolutionStrategy("lowest")).toBe("lowest"); - - expect(() => getResolutionStrategy("invalid")).toThrow( - "Invalid resolution-strategy: invalid. Must be 'highest' or 'lowest'.", - ); - }); -}); diff --git a/__tests__/utils/resolution-strategy.test.ts b/__tests__/utils/resolution-strategy.test.ts deleted file mode 100644 index 7715520..0000000 --- a/__tests__/utils/resolution-strategy.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -jest.mock("@actions/core", () => { - return { - debug: jest.fn(), - getBooleanInput: jest.fn( - (name: string) => (mockInputs[name] ?? "") === "true", - ), - getInput: jest.fn((name: string) => mockInputs[name] ?? ""), - }; -}); - -import { beforeEach, describe, expect, it, jest } from "@jest/globals"; - -// Will be mutated per test before (re-)importing the module under test -let mockInputs: Record = {}; - -describe("resolutionStrategy", () => { - beforeEach(() => { - jest.resetModules(); - mockInputs = {}; - }); - - it("returns 'highest' when input not provided", async () => { - const { resolutionStrategy } = await import("../../src/utils/inputs"); - expect(resolutionStrategy).toBe("highest"); - }); - - it("returns 'highest' when input is 'highest'", async () => { - mockInputs["resolution-strategy"] = "highest"; - const { resolutionStrategy } = await import("../../src/utils/inputs"); - expect(resolutionStrategy).toBe("highest"); - }); - - it("returns 'lowest' when input is 'lowest'", async () => { - mockInputs["resolution-strategy"] = "lowest"; - const { resolutionStrategy } = await import("../../src/utils/inputs"); - expect(resolutionStrategy).toBe("lowest"); - }); - - it("throws error for invalid input", async () => { - mockInputs["resolution-strategy"] = "invalid"; - await expect(import("../../src/utils/inputs")).rejects.toThrow( - "Invalid resolution-strategy: invalid. Must be 'highest' or 'lowest'.", - ); - }); -});