diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a103d12 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +name: CI + +on: + pull_request: + push: + branches: + - master + +jobs: + test: + name: Test - ${{ matrix.os }} + runs-on: ${{ matrix.runner }} + timeout-minutes: 1 + strategy: + max-parallel: 1 + matrix: + include: + - os: linux + runner: ubuntu-latest + - os: windows + runner: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up external foreman + run: | + cp foreman-extern.toml foreman.toml + + - name: Get foreman and run foreman install + uses: Roblox/setup-foreman@v3 + with: + version: "^1.0.0" + token: ${{ secrets.GITHUB_TOKEN }} + allow-external-github-orgs: true + + - name: Run tests + env: + LOG_NO_COLOR: 1 + ROBLOX_API_KEY: ${{ secrets.ROBLOX_API_KEY }} + TEST_UNIVERSE_ID: ${{ secrets.TEST_UNIVERSE_ID }} + TEST_PLACE_ID: ${{ secrets.TEST_PLACE_ID }} + run: | + lute scripts/test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0f21bb8 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,70 @@ +name: Release + +on: + push: + tags: ["v*.*.*"] + +jobs: + build: + name: Build - ${{ matrix.os }} + runs-on: ${{ matrix.runner }} + timeout-minutes: 1 + strategy: + matrix: + include: + - os: macos + runner: macos-latest + artifact_path: "build/rocale-cli" + - os: linux + runner: ubuntu-latest + artifact_path: "build/rocale-cli" + - os: windows + runner: windows-latest + artifact_path: "build/rocale-cli.exe" + steps: + - uses: actions/checkout@v4 + + - name: Generate access token + uses: Roblox-ActionsCache/tibdex-github-app-token@v1.4.0 + id: setup_token + with: + app_id: ${{ secrets.TOKENS_APP_LUA_ECOSYSTEM_DEPENDENCIES_ID }} + private_key: ${{ secrets.TOKENS_APP_LUA_ECOSYSTEM_DEPENDENCIES_KEY }} + + - name: Get foreman and run foreman install + uses: Roblox/setup-foreman@v3 + with: + version: "^1.0.0" + token: ${{ steps.setup_token.outputs.token }} + allow-external-github-orgs: true + + - name: Build release artifacts + run: | + lute scripts/build + + - uses: actions/upload-artifact@v5 + with: + name: rocale-cli-${{ matrix.os }}-x86_64 + path: ${{ matrix.artifact_path }} + + release: + runs-on: ubuntu-latest + timeout-minutes: 3 + needs: build + steps: + - uses: actions/download-artifact@v5 + with: + path: artifacts + + - name: Zip release artifacts + run: | + zip -rj rocale-cli-macos-x86_64.zip ./artifacts/rocale-cli-macos-x86_64/* + zip -rj rocale-cli-linux-x86_64.zip ./artifacts/rocale-cli-linux-x86_64/* + zip -rj rocale-cli-windows-x86_64.zip ./artifacts/rocale-cli-windows-x86_64/* + + - uses: Roblox-ActionsCache/softprops-action-gh-release@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + draft: true + files: | + rocale-cli-*.zip diff --git a/.gitignore b/.gitignore index 3094469..9a0215e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .DS_Store build +.env +output.rbxl diff --git a/foreman-extern.toml b/foreman-extern.toml new file mode 100644 index 0000000..3a6c4c7 --- /dev/null +++ b/foreman-extern.toml @@ -0,0 +1,6 @@ +[tools] +lute = { source = "luau-lang/lute", version = "=0.1.0-nightly.20251106" } +selene = { source = "Kampfkarren/selene", version = "0.29.0" } +stylua = { source = "JohnnyMorganz/StyLua", version = "2.0.1" } +darklua = { github = "seaofvoices/darklua", version = "=0.17.1" } +rojo = { source = "rojo-rbx/rojo", version = "7.3.0" } diff --git a/foreman.toml b/foreman.toml index 05f294d..aa76c73 100644 --- a/foreman.toml +++ b/foreman.toml @@ -3,3 +3,4 @@ lute = { source = "luau-lang/lute", version = "=0.1.0-nightly.20251106" } selene = { source = "Roblox/Kampfkarren-selene", version = "0.29.0" } stylua = { source = "Roblox/JohnnyMorganz-StyLua", version = "2.0.1" } darklua = { github = "seaofvoices/darklua", version = "=0.17.1" } +rojo = { source = "Roblox/rojo-rbx-rojo", version = "7.3.0" } diff --git a/scripts/build.luau b/scripts/build.luau index 5cbb812..e4415d0 100644 --- a/scripts/build.luau +++ b/scripts/build.luau @@ -1,4 +1,5 @@ local fs = require("@lute/fs") +local system = require("@lute/system") local log = require("../src/util/log") log.setLevel("debug") @@ -9,7 +10,12 @@ if not fs.exists("build") then fs.mkdir("build") end +local output_path = "build/rocale-cli" +if string.lower(system.os) == "windows_nt" then + output_path = output_path .. ".exe" +end + log.info("Building rocale-cli...") runProcess({ "darklua", "process", "src/cli.luau", "build/cli.luau" }) -- Remove when lute compile supports aliases -runProcess({ "lute", "compile", "build/cli.luau", "--output", "build/rocale-cli", "--show-require-graph" }) -log.info("Build complete: build/rocale-cli") +runProcess({ "lute", "compile", "build/cli.luau", "--output", output_path, "--show-require-graph" }) +log.info("Build complete: " .. output_path) diff --git a/scripts/test.luau b/scripts/test.luau new file mode 100644 index 0000000..8e1b506 --- /dev/null +++ b/scripts/test.luau @@ -0,0 +1,25 @@ +local process = require("@lute/process") + +local log = require("../src/util/log") +log.setLevel("debug") + +local runProcess = require("../src/util/runProcess") + +runProcess({ + "lute", + "scripts/build", +}) + +runProcess({ + "build/rocale-cli", + "run", + "--script", + "tests/run-test-project.luau", + "--placeId", + process.env.TEST_PLACE_ID, + "--universeId", + process.env.TEST_UNIVERSE_ID, + "--load.project", + "tests/test.project.json", + "--verbose", +}) diff --git a/src/util/log.luau b/src/util/log.luau index 329cabe..ae4e93f 100644 --- a/src/util/log.luau +++ b/src/util/log.luau @@ -10,7 +10,12 @@ local log = {} type Level = "trace" | "debug" | "info" | "warn" | "error" local currentLevel: Level = "info" + local colorsEnabled = true -- set to false to disable colors +if process.env.LOG_NO_COLOR then + colorsEnabled = false +end + local showCaller = true -- set to false to disable caller information local levels = { diff --git a/tests/project/init.luau b/tests/project/init.luau new file mode 100644 index 0000000..b30e187 --- /dev/null +++ b/tests/project/init.luau @@ -0,0 +1 @@ +return true diff --git a/tests/run-test-project.luau b/tests/run-test-project.luau new file mode 100644 index 0000000..ad323fc --- /dev/null +++ b/tests/run-test-project.luau @@ -0,0 +1,6 @@ +local ReplicatedStorage = game:GetService("ReplicatedStorage") + +local TestProject = require(ReplicatedStorage:FindFirstChild("TestProject")) +assert(TestProject == true, "TestProject did not return true") + +return diff --git a/tests/test.project.json b/tests/test.project.json new file mode 100644 index 0000000..51e4420 --- /dev/null +++ b/tests/test.project.json @@ -0,0 +1,11 @@ +{ + "name": "TestProject", + "tree": { + "$className": "DataModel", + "ReplicatedStorage": { + "TestProject": { + "$path": "project" + } + } + } +}