Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
a4c10fe
Move Lune scripts to `scripts`
vocksel Oct 23, 2025
d8a6f28
Add `lute` as a dependency
vocksel Oct 23, 2025
1707027
Change all `lune run foo` commands to `lute scripts/foo.luau`
vocksel Oct 23, 2025
435cbc9
Port most of the codebase over
vocksel Oct 23, 2025
5fea6e8
Enable new solver in VSCode too
vocksel Oct 23, 2025
e198d35
Update examples
vocksel Oct 23, 2025
6af46e1
Resolve a bunch of the type errors
vocksel Oct 23, 2025
6d225c6
Use macos-latest to Lute can spawn processes
vocksel Oct 23, 2025
68906a7
Add alias for `std`
vocksel Oct 23, 2025
d8023ad
Update .luaurc
vocksel Oct 23, 2025
76a913a
Update tests to use Lute's builtin test library
vocksel Oct 23, 2025
4454881
Setup Lute typedefs when installing
vocksel Oct 24, 2025
4863922
Bump Lute nightly version
vocksel Nov 6, 2025
d9c8b80
Tests runner almost works but can't resolve @std/test for some reason
vocksel Nov 6, 2025
d3da756
Update `run.luau`
vocksel Nov 6, 2025
cc3afe9
Patch up some analysis errors
vocksel Nov 6, 2025
6196bef
Bump Lute version
vocksel Dec 3, 2025
e38e1c8
Get tests running again
vocksel Dec 3, 2025
dfbeb60
Getl inting running again
vocksel Dec 3, 2025
703351e
Just let tests break CI for now
vocksel Dec 9, 2025
d88800f
Get logs showing up again
vocksel Dec 9, 2025
6e7c012
Don't need to set the reporter ourselves
vocksel Dec 9, 2025
4dec21d
Remove duplicate line in README
vocksel Dec 10, 2025
929aab3
Merge remote-tracking branch 'origin/main' into MUS-2390-rewrite-with…
vocksel Dec 10, 2025
9f76fd0
Merge remote-tracking branch 'origin/main' into MUS-2390-rewrite-with…
vocksel Dec 17, 2025
d71b5b7
Run all tests from a single entrypoint
vocksel Dec 17, 2025
f46be8a
Update E2E tests to work with Lute
vocksel Dec 17, 2025
35f0208
Fix up most unit tests
vocksel Dec 17, 2025
17f3023
Get analysis working better
vocksel Dec 17, 2025
4435e01
Remove lingering usage of Lune
vocksel Dec 17, 2025
4221bc4
Go back to ubuntu-latest runners
vocksel Dec 17, 2025
9e80c67
Mereg MUS-2430-assets-api-for-uploads
vocksel Dec 17, 2025
48dbd07
pcall has been thwarted
vocksel Dec 17, 2025
ad572cc
Merge remote-tracking branch 'origin/main' into MUS-2390-rewrite-with…
vocksel Dec 18, 2025
14c8f5f
Cast all json.deserialize results to `any`
vocksel Dec 18, 2025
2f2bc60
Extend the TOML battery to work with quoted keys
vocksel Dec 18, 2025
0cc19e0
Add upstream link
vocksel Dec 18, 2025
541db42
Fix paths to deploy scripts
vocksel Dec 18, 2025
c46534e
Add color back to the terminal
vocksel Dec 18, 2025
e429140
Pretty print tables when logging
vocksel Dec 18, 2025
e7f9585
Bump Lute version to 0.1.0-nightly.20251217
vocksel Dec 18, 2025
78f7a84
Update how files are accessed
vocksel Dec 18, 2025
4aff454
Deploy scripts just grab from the environment
vocksel Dec 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ROBLOX_API_KEY=
LOG_LEVEL=info
32 changes: 6 additions & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,10 @@ jobs:
allow-external-github-orgs: true

- name: Install dependencies
run: lune run install
run: lute scripts/install.luau

- name: Run unit tests
run: lune run test

test-e2e:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4

- uses: Roblox/setup-foreman@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
allow-external-github-orgs: true

- name: Install dependencies
run: lune run install

- name: Run end-to-end tests
run: lune run test-e2e
run: lute scripts/test.luau --e2e
env:
ROBLOX_API_KEY: ${{ secrets.ROBLOX_API_KEY }}

Expand All @@ -55,10 +38,10 @@ jobs:
allow-external-github-orgs: true

- name: Install dependencies
run: lune run install
run: lute scripts/install.luau

- name: Lint
run: lune run lint
run: lute scripts/lint.luau

analyze:
runs-on: ubuntu-latest
Expand All @@ -72,12 +55,9 @@ jobs:
allow-external-github-orgs: true

- name: Install dependencies
run: lune run install

- name: Setup Lune typedefs
run: lune setup
run: lute scripts/install.luau

# MUS-2103 TODO: This will error in CI until Foreman is updated to install
# the correct linux binary for luau-lsp
- name: Analyze
run: lune run analyze
run: lute scripts/analyze.luau
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
allow-external-github-orgs: true

- name: Install dependencies
run: lune run install
run: lute scripts/install.luau

- name: Build
run: lune run build
run: lute scripts/build.luau

- uses: actions/upload-artifact@v4
with:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Secrets
.env

# Build artifacts
build
temp
Expand Down
7 changes: 4 additions & 3 deletions .luaurc
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"languageMode": "strict",
"aliases": {
"root": "src",
"examples": "examples",
"lute": "~/.lute/typedefs/0.1.0/lute/",
"std": "~/.lute/typedefs/0.1.0/std/",
"pkg": "pkg",
"lune": "~/.lune/.typedefs/0.9.3"
"root": "src",
"examples": "examples"
}
}
9 changes: 0 additions & 9 deletions .lune/analyze.luau

This file was deleted.

32 changes: 0 additions & 32 deletions .lune/install.luau

This file was deleted.

28 changes: 0 additions & 28 deletions .lune/test-e2e.luau

This file was deleted.

28 changes: 0 additions & 28 deletions .lune/test.luau

This file was deleted.

7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"luau-lsp.fflags.override": {
"LuauSolverV2": "true"
},
"luau-lsp.platform.type": "standard",
"luau-lsp.ignoreGlobs": ["**/pkg/**"]
}
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Deploy rbxm files from GitHub to the Creator Store.
# Installation

> [!NOTE]
> [Lune](https://github.com/lune-org/lune) v0.9.3+ is required.
> [Lute](https://github.com/luau-lang/lute) v0.1.0-nightly.20251217+ is required.

## Prebuilt zip (recommended)

Expand All @@ -24,8 +24,8 @@ Run the following commands to clone the repo, install dependencies, and build rb
git clone https://github.com/Roblox/rbxasset.git
cd rbxasset
foreman install
lune run install
lune run build
lute scripts/install.luau
lute scripts/build.luau
```

From there, drag and drop `build/rbxasset` to a place where you will require it via a Luau script.
Expand Down Expand Up @@ -54,25 +54,27 @@ This defines a `default` asset and a `production` environment to deploy to.
Then create a Luau script to handle the deployment:

```luau
-- .lune/publish.luau
local process = require("@lune/process")
-- scripts/publish.luau
local process = require("@lute/process")

local rbxasset = require("./path/to/rbxasset")

local apiKey = process.args[1]
local args = { ... }

local apiKey = args[1]
assert(apiKey, "argument #1 must be a valid Open Cloud API key")

-- The rbxm file needs to be built manually. rbxasset makes no assumptions about
-- how your project is setup, it only cares about having a file to upload. Note
-- the filename `build.rbxm` matches the `model` field in rbxasset.toml
process.exec("rojo", { "build", "-o", "build.rbxm" })
process.run("rojo build -o build.rbxm")

-- Publish the `default` asset defined in rbxasset.toml
rbxasset.publishPackageAsync(process.cwd, "default", apiKey)
rbxasset.publishPackageAsync(process.cwd(), "default", apiKey)
```

```sh
$ lune run publish <API_KEY>
$ lute scripts/publish.luau <API_KEY>
```

Where `<API_KEY>` represents an Open Cloud API key that has the following scopes:
Expand All @@ -94,7 +96,6 @@ Assets define how the asset will be deployed and shown on the Creator Store.
| `environment` | `string` | Defines which environment to deploy to. This value must equal one of the environments defined in the `environments` object |
| `description` | `string?` | The description of the asset on the Creator Store |
| `icon` | `string?` | Path to the icon (png only) to display on the Creator Store |
| `description` | `string?` | The description of the asset on the Creator Store |
| `type` | `"Package" \| "Plugin"` | The type of asset to upload to the Creator Store. This must be set before the first publish as asset type is immutable once uploaded. Defaults to `"Package"` |

## Environments
Expand Down
13 changes: 5 additions & 8 deletions examples/package/deploy.luau
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
local rbxasset = require("@root/")
local rbxasset = require("@root/init")

local process = require("@lune/process")
local process = require("@lute/process")

local apiKey = process.args[1]
assert(apiKey, "argument #1 must be a valid Open Cloud API key")
assert(process.cwd():match("examples/package"), "you must be in the `examples/package` folder when running this script")

assert(process.cwd:match("examples/package"), "you must be in the `examples/package` folder when running this script")
process.system("rojo build -o asset.rbxm")

process.exec("rojo", { "build", "-o", "asset.rbxm" })

rbxasset.publishPackageAsync(process.cwd, "package", apiKey)
rbxasset.publishPackageAsync(process.cwd(), "package", process.env.ROBLOX_API_KEY)
59 changes: 38 additions & 21 deletions examples/package/e2e.spec.luau
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
local frktest = require("@pkg/frktest")
local fs = require("@lune/fs")
local process = require("@lune/process")
local serde = require("@lune/serde")
local expect = require("@std/test/assert")
local fs = require("@lute/fs")
local process = require("@lute/process")
local test = require("@std/test")
local toml = require("@root/lib/toml")

local getAssetDetailsAsync = require("@root/requests/getAssetDetailsAsync")
local getOrCreateAssetLockfile = require("@root/manifest/getOrCreateAssetLockfile")
local readManifest = require("@root/manifest/readManifest")
local run = require("@root/lib/run")

local test = frktest.test
local check = frktest.assert.check

local ROOT_PATH = "examples/package"
local MANIFEST_PATH = `{ROOT_PATH}/rbxasset.toml`

local function appendTextForTesting(path: string, text: string)
local content = fs.readFile(path)
local handle = fs.open(path, "w")
local content = fs.read(handle)
content ..= text
fs.writeFile(path, content)
fs.write(handle, content)
fs.close(handle)
end

local apiKey = process.env.ROBLOX_API_KEY
assert(apiKey, "End-to-end tests can only be run when the ROBLOX_API_KEY envvar is set to a valid Open Cloud API key")
if not apiKey then
error("End-to-end tests can only be run when the ROBLOX_API_KEY envvar is set to a valid Open Cloud API key")
end

local lockfile = getOrCreateAssetLockfile(ROOT_PATH)
local assetId = lockfile.assets.package.assetId
Expand All @@ -38,7 +40,10 @@ test.case("uploads rbxm to the Creator Store", function()
appendTextForTesting(path, `\nprint("New!")`)

local success, result = pcall(function()
run("lune", { "run", "deploy.luau", apiKey }, {
return run("lute", { "deploy.luau" }, {
env = {
ROBLOX_API_KEY = apiKey,
},
cwd = ROOT_PATH,
})
end)
Expand All @@ -49,7 +54,7 @@ test.case("uploads rbxm to the Creator Store", function()

assetDetails = getAssetDetailsAsync(assetId, apiKey)

check.not_equal(assetDetails.revisionId, prevRevisionId)
expect.neq(assetDetails.revisionId, prevRevisionId)
end)

test.case("text fields in rbxasest.toml get mirrored to the asset details", function()
Expand All @@ -62,31 +67,43 @@ test.case("text fields in rbxasest.toml get mirrored to the asset details", func
manifest.assets.package.name = `{manifest.assets.package.name}\n({id})`
manifest.assets.package.description = `{manifest.assets.package.description}\n({id})`

fs.writeFile(MANIFEST_PATH, serde.encode("toml", manifest))
local handle = fs.open(MANIFEST_PATH, "w")
fs.write(handle, toml.serialize(manifest))
fs.close(handle)

run("lune", { "run", "deploy.luau", apiKey }, {
cwd = ROOT_PATH,
})
local success, result = pcall(function()
return run("lute", { "deploy.luau" }, {
env = {
ROBLOX_API_KEY = apiKey,
},
cwd = ROOT_PATH,
})
end)

run("git", { "restore", MANIFEST_PATH })

assert(success, result)

assetDetails = getAssetDetailsAsync(assetId, apiKey)

check.equal(assetDetails.displayName, manifest.assets.package.name)
check.equal(assetDetails.description, manifest.assets.package.description)
check.not_equal(assetDetails.revisionId, prevRevisionId)
expect.eq(assetDetails.displayName, manifest.assets.package.name)
expect.eq(assetDetails.description, manifest.assets.package.description)
expect.neq(assetDetails.revisionId, prevRevisionId)
end)

test.case("does not publish a new version when there are no changes", function()
local assetDetails = getAssetDetailsAsync(assetId, apiKey)

local prevRevisionId = assetDetails.revisionId

run("lune", { "run", "deploy.luau", apiKey }, {
run("lute", { "deploy.luau" }, {
env = {
ROBLOX_API_KEY = apiKey,
},
cwd = ROOT_PATH,
})

assetDetails = getAssetDetailsAsync(assetId, apiKey)

check.equal(assetDetails.revisionId, prevRevisionId)
expect.eq(assetDetails.revisionId, prevRevisionId)
end)
Loading
Loading