Skip to content

Commit 5a01557

Browse files
authored
Merge pull request #8 from yuchanns/ci/auto-build
feat(ci): add nightly build
2 parents 8e5b147 + f312d25 commit 5a01557

File tree

5 files changed

+283
-14
lines changed

5 files changed

+283
-14
lines changed

.github/workflows/nightly.yml

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
name: Nightly Build
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
pull_request:
8+
branches:
9+
- master
10+
workflow_dispatch:
11+
schedule:
12+
- cron: '0 0 * * *' # Runs every day at midnight UTC
13+
14+
jobs:
15+
check:
16+
name: Determine Build Necessity
17+
runs-on: ubuntu-latest
18+
outputs:
19+
proceed: ${{ steps.check.outputs.proceed }}
20+
steps:
21+
- uses: actions/checkout@v5
22+
with:
23+
fetch-depth: 0
24+
- name: Get the last nightly commit
25+
id: last_nightly
26+
uses: actions/github-script@v7
27+
with:
28+
script: |
29+
const releases = await github.rest.repos.listReleases({
30+
owner: context.repo.owner,
31+
repo: context.repo.repo,
32+
per_page: 100
33+
});
34+
const nightlyRelease = releases.data.find(release => release.tag_name.includes('nightly') || release.name.includes('Nightly'));
35+
if (nightlyRelease) {
36+
const tagName = nightlyRelease.tag_name;
37+
const tag = await github.rest.git.getRef({
38+
owner: context.repo.owner,
39+
repo: context.repo.repo,
40+
ref: `tags/${tagName}`
41+
});
42+
const commitSha = tag.data.object.sha;
43+
return commitSha;
44+
} else {
45+
return null;
46+
}
47+
- name: Check the proceed condition
48+
id: check
49+
run: |
50+
LAST_NIGHTLY_COMMIT="${{ steps.last_nightly.outputs.result }}"
51+
CURRENT_COMMIT="${GITHUB_SHA}"
52+
echo "Last nightly commit: $LAST_NIGHTLY_COMMIT"
53+
echo "Current commit: $CURRENT_COMMIT"
54+
if [ -z "$LAST_NIGHTLY_COMMIT" ]; then
55+
echo "No previous nightly release found. Proceeding with build."
56+
echo "proceed=true" >> $GITHUB_OUTPUT
57+
elif [ "$LAST_NIGHTLY_COMMIT" != "$CURRENT_COMMIT" ]; then
58+
echo "New commits found since last nightly release. Proceeding with build."
59+
echo "proceed=true" >> $GITHUB_OUTPUT
60+
else
61+
echo "No new commits since last nightly release. Skipping build."
62+
echo "proceed=false" >> $GITHUB_OUTPUT
63+
fi
64+
build:
65+
name: Nightly Build on ${{ matrix.os }}
66+
needs: check
67+
if: needs.check.outputs.proceed == 'true'
68+
runs-on: ${{ matrix.os }}
69+
strategy:
70+
fail-fast: false
71+
matrix:
72+
os: [windows-latest, macos-latest]
73+
steps:
74+
- uses: actions/checkout@v5
75+
with:
76+
submodules: recursive
77+
- uses: actions/checkout@v5
78+
with:
79+
repository: floooh/sokol-tools-bin
80+
ref: "c240bd1d17d4192572ee6e0cdb6e2477e4a7df80"
81+
path: sokol-tools-bin
82+
fetch-depth: 1
83+
- name: Setup sokol-shdc
84+
shell: bash
85+
run: |
86+
if [[ "$RUNNER_OS" == "Windows" ]]; then
87+
TARGET_DIR="C:/Windows/System32"
88+
SHDC_BINARY="sokol-shdc.exe"
89+
FIND_PATH="bin/win32"
90+
elif [[ "$RUNNER_OS" == "macOS" ]]; then
91+
TARGET_DIR="/usr/local/bin"
92+
SHDC_BINARY="sokol-shdc"
93+
FIND_PATH="bin/osx_arm64"
94+
else # Linux
95+
TARGET_DIR="/usr/local/bin"
96+
SHDC_BINARY="sokol-shdc"
97+
FIND_PATH="bin/linux"
98+
fi
99+
echo "Setting up sokol-tools from sokol-tools-bin/$FIND_PATH"
100+
find sokol-tools-bin/$FIND_PATH -name $SHDC_BINARY -exec cp {} $TARGET_DIR \;
101+
$SHDC_BINARY -h
102+
- uses: yuchanns/actions-luamake@v1.0.0
103+
with:
104+
luamake-version: "5bedfce66f075a9f68b1475747738b81b3b41c25"
105+
- name: Build
106+
shell: bash
107+
id: build
108+
run: |
109+
luamake precompile
110+
luamake soluna
111+
if [[ "$RUNNER_OS" == "Windows" ]]; then
112+
SOLUNA_BINARY="soluna.exe"
113+
RENAME_BINARY="soluna-windows-amd64.exe"
114+
else
115+
SOLUNA_BINARY="soluna"
116+
RENAME_BINARY="soluna-macos-arm64"
117+
fi
118+
SOLUNA_PATH=$(find bin -name $SOLUNA_BINARY | head -n 1)
119+
cp "$SOLUNA_PATH" "bin/$RENAME_BINARY"
120+
echo "SOLUNA_PATH=bin/$RENAME_BINARY" >> $GITHUB_OUTPUT
121+
echo "SOLUNA_BINARY=$RENAME_BINARY" >> $GITHUB_OUTPUT
122+
- uses: actions/upload-artifact@v4
123+
name: Upload
124+
if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
125+
with:
126+
name: "soluna-${{ runner.os }}-${{ steps.build.outputs.SOLUNA_BINARY }}"
127+
if-no-files-found: "error"
128+
path: "${{ steps.build.outputs.SOLUNA_PATH }}"
129+
overwrite: "true"
130+
release:
131+
name: Create Nightly Release
132+
needs: [check, build]
133+
runs-on: ubuntu-latest
134+
if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
135+
permissions:
136+
contents: write
137+
steps:
138+
- uses: actions/checkout@v5
139+
- name: Download all artifacts
140+
uses: actions/download-artifact@v5
141+
with:
142+
path: artifacts
143+
- name: Prepare release assets
144+
run: |
145+
mkdir -p release-assets
146+
find artifacts -type f -name "soluna*" -exec cp {} release-assets/ \;
147+
ls -la release-assets/
148+
- name: Delete existing nightly releases
149+
uses: actions/github-script@v7
150+
with:
151+
script: |
152+
const releases = await github.rest.repos.listReleases({
153+
owner: context.repo.owner,
154+
repo: context.repo.repo,
155+
per_page: 100
156+
});
157+
158+
for (const release of releases.data) {
159+
if (release.tag_name.includes('nightly') || release.name.includes('Nightly')) {
160+
console.log(`Deleting release: ${release.tag_name}`);
161+
try {
162+
await github.rest.repos.deleteRelease({
163+
owner: context.repo.owner,
164+
repo: context.repo.repo,
165+
release_id: release.id
166+
});
167+
168+
try {
169+
await github.rest.git.deleteRef({
170+
owner: context.repo.owner,
171+
repo: context.repo.repo,
172+
ref: `tags/${release.tag_name}`
173+
});
174+
} catch (error) {
175+
console.log(`Tag ${release.tag_name} might not exist or already deleted`);
176+
}
177+
} catch (error) {
178+
console.log(`Failed to delete release ${release.tag_name}: ${error.message}`);
179+
}
180+
}
181+
}
182+
- name: Create nightly release
183+
id: create-release
184+
uses: actions/github-script@v7
185+
with:
186+
script: |
187+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
188+
const commitSha = context.sha.substring(0, 7);
189+
const tagName = 'nightly';
190+
const releaseNotes = `🌙 **Nightly Build**
191+
192+
**Build Information:**
193+
- **Commit:** \`${context.sha}\`
194+
- **Branch:** \`${context.ref.replace('refs/heads/', '')}\`
195+
- **Build Time:** \`${new Date().toISOString()}\`
196+
- **Workflow:** [${context.runId}](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
197+
198+
**Assets:**
199+
- soluna-windows-amd64.exe
200+
- soluna-macos-arm64
201+
202+
> ⚠️ **Note:** This is an automated nightly build. It may contain unstable features and bugs.
203+
>
204+
> 📦 **Previous nightly releases are automatically removed to keep the repository clean.`;
205+
206+
const { data } = await github.rest.repos.createRelease({
207+
owner: context.repo.owner,
208+
repo: context.repo.repo,
209+
tag_name: tagName,
210+
name: `Nightly Build (${timestamp})`,
211+
body: releaseNotes,
212+
prerelease: true,
213+
make_latest: 'false'
214+
});
215+
216+
console.log(`Created release: ${data.html_url}`);
217+
return data.id;
218+
- name: Upload release assets
219+
uses: actions/github-script@v7
220+
with:
221+
script: |
222+
const fs = require('fs');
223+
const path = require('path');
224+
const releaseId = ${{ steps.create-release.outputs.result }};
225+
226+
const assetsDir = 'release-assets';
227+
const files = fs.readdirSync(assetsDir);
228+
229+
for (const file of files) {
230+
const filePath = path.join(assetsDir, file);
231+
const stats = fs.statSync(filePath);
232+
233+
if (stats.isFile()) {
234+
console.log(`Uploading ${file}...`);
235+
236+
const content = fs.readFileSync(filePath);
237+
238+
await github.rest.repos.uploadReleaseAsset({
239+
owner: context.repo.owner,
240+
repo: context.repo.repo,
241+
release_id: releaseId,
242+
name: file,
243+
data: content
244+
});
245+
246+
console.log(`✅ Uploaded ${file}`);
247+
}
248+
}

clibs/ltask/make.lua

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ local lm = require "luamake"
33
lm.rootdir = lm.basedir .. "/3rd/ltask"
44

55
lm:source_set "ltask_src" {
6-
deps = {
7-
"soluna_src",
8-
},
96
sources = {
107
"src/*.c",
118
},

clibs/sokol/make.lua

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
local lm = require "luamake"
22
local fs = require "bee.filesystem"
33

4-
local function compile_shader(src, target, lang)
5-
lm:runlua {
4+
local deps = {}
5+
6+
local function compile_shader(src, name, lang)
7+
local dep = name .. "_shader"
8+
deps[#deps+1] = dep
9+
local target = lm.builddir .. "/" .. name
10+
lm:runlua (dep) {
611
script = lm.basedir .. "/clibs/sokol/shader2c.lua",
712
inputs = lm.basedir .. "/" .. src,
813
outputs = lm.basedir .. "/" .. target,
@@ -20,6 +25,10 @@ for path in fs.pairs("src") do
2025
lm.os == "macos" and "metal_macos" or "unknown"
2126
if path:extension() == ".glsl" then
2227
local base = path:stem():string()
23-
compile_shader(path:string(), lm.builddir .. "/" .. base .. ".glsl.h", lang)
28+
compile_shader(path:string(), base .. ".glsl.h", lang)
2429
end
2530
end
31+
32+
lm:phony "compile_shaders" {
33+
deps = deps,
34+
}

clibs/yoga/make.lua

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@ lm:source_set "yoga_src" {
1313
}
1414
}
1515

16-
local function compile_lua_code(script, src, target)
17-
local outputs = lm.basedir .. "/" .. target
18-
lm:runlua {
16+
local deps = {}
17+
18+
local function compile_lua_code(script, src, name)
19+
local dep = name .. "_lua_code"
20+
deps[#deps+1] = dep
21+
local target = lm.builddir .. "/" .. name
22+
lm:runlua (dep) {
1923
script = lm.basedir .. "/clibs/yoga/runlua.lua",
2024
deps = {
2125
"yoga_src",
2226
"lua",
2327
},
2428
inputs = lm.basedir .. "/" .. src,
25-
outputs = outputs,
29+
outputs = lm.basedir .. "/" .. target,
2630
args = {
2731
lm.bindir,
2832
lm.basedir .. "/" .. script,
@@ -40,17 +44,21 @@ local lua_code_src = {
4044
}
4145

4246
for _, dir in ipairs(lua_code_src) do
43-
for path in fs.pairs(dir) do
47+
for path in fs.pairs(lm.basedir .. "/" .. dir) do
4448
if path:extension() == ".lua" then
4549
local base = path:stem():string()
46-
compile_lua_code("script/lua2c.lua", path:string(), lm.builddir .. "/" .. base .. ".lua.h")
50+
compile_lua_code("script/lua2c.lua", path:string(), base .. ".lua.h")
4751
end
4852
end
4953
end
5054

5155
for path in fs.pairs("src/data") do
5256
if path:extension() == ".dl" then
5357
local base = path:stem():string()
54-
compile_lua_code("script/datalist2c.lua", path:string(), lm.builddir .. "/" .. base .. ".dl.h")
58+
compile_lua_code("script/datalist2c.lua", path:string(), base .. ".dl.h")
5559
end
5660
end
61+
62+
lm:phony "compile_lua_code" {
63+
deps = deps,
64+
}

make.lua

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,15 @@ lm:exe "soluna" {
7777
"soluna_src",
7878
"ltask_src",
7979
"yoga_src",
80+
"compile_lua_code",
81+
"compile_shaders",
8082
"datalist_src",
8183
},
8284
}
8385

84-
lm:default "soluna"
86+
lm:phony "precompile" {
87+
deps = {
88+
"compile_shaders",
89+
"compile_lua_code",
90+
},
91+
}

0 commit comments

Comments
 (0)