Skip to content

Commit 7b1e6f3

Browse files
authored
feat(apps): add pure rust binaries and release to github (#15469)
closes #14903
1 parent d32d22e commit 7b1e6f3

File tree

14 files changed

+268
-113
lines changed

14 files changed

+268
-113
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: "Archive Binary"
2+
description: "Archives a single binary using platform-appropriate compression (zip for Windows, tar.gz for Unix)"
3+
inputs:
4+
source_path:
5+
description: "Path to the source binary file"
6+
required: true
7+
binary_name:
8+
description: "Name for the binary file inside the archive (can include extension like .exe or .node)"
9+
required: true
10+
archive_name:
11+
description: "Name for the archive file without extension (extension will be added based on platform)"
12+
required: true
13+
14+
runs:
15+
using: "composite"
16+
steps:
17+
- name: Archive Binary (Windows)
18+
if: runner.os == 'Windows'
19+
shell: bash
20+
run: |
21+
mv "${INPUTS_SOURCE_PATH}" "${INPUTS_BINARY_NAME}"
22+
7z a "${INPUTS_ARCHIVE_NAME}.zip" "${INPUTS_BINARY_NAME}"
23+
env:
24+
INPUTS_SOURCE_PATH: ${{ inputs.source_path }}
25+
INPUTS_BINARY_NAME: ${{ inputs.binary_name }}
26+
INPUTS_ARCHIVE_NAME: ${{ inputs.archive_name }}
27+
28+
- name: Archive Binary (Unix)
29+
if: runner.os != 'Windows'
30+
shell: bash
31+
run: |
32+
mv "${INPUTS_SOURCE_PATH}" "${INPUTS_BINARY_NAME}"
33+
tar czf "${INPUTS_ARCHIVE_NAME}.tar.gz" "${INPUTS_BINARY_NAME}"
34+
env:
35+
INPUTS_SOURCE_PATH: ${{ inputs.source_path }}
36+
INPUTS_BINARY_NAME: ${{ inputs.binary_name }}
37+
INPUTS_ARCHIVE_NAME: ${{ inputs.archive_name }}

.github/workflows/release_apps.yml

Lines changed: 92 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ jobs:
8585

8686
name: Build Oxlint ${{ matrix.code-target }}
8787
runs-on: ${{ matrix.os }}
88+
env:
89+
TARGET_CC: clang # for mimalloc
8890
defaults:
8991
run:
9092
shell: bash
@@ -109,53 +111,58 @@ jobs:
109111
with:
110112
version: 0.13.0
111113

112-
- name: Build oxlint
114+
- name: Build oxlint for node.js
113115
working-directory: apps/oxlint
114116
run: pnpm run build-napi-release --target ${{ matrix.target }} ${{ matrix.build-oxlint-args }}
115-
shell: bash
116-
env:
117-
TARGET_CC: clang # for mimalloc
117+
118+
- name: Build Rust binary
119+
run: cross build --release -p oxlint --features allocator --target=${{ matrix.target }}
118120

119121
- name: Build language server
120-
shell: bash
121-
env:
122-
TARGET_CC: clang # for mimalloc
123122
run: cross build --release -p oxc_language_server --bin oxc_language_server --target=${{ matrix.target }}
124123

125124
# The binaries are zipped to fix permission loss https://github.com/actions/upload-artifact#permission-loss
126-
- name: Archive Binaries
127-
if: runner.os == 'Windows'
128-
# Windows `.node` files have `-msvc` postfix e.g. `oxlint.win32-x64-msvc.node`. Remove the postfix.
129-
run: |
130-
OXLINT_BIN_SRC_NAME=oxlint.${{ matrix.code-target }}-msvc.node
131-
OXLINT_BIN_NAME=oxlint.${{ matrix.code-target }}.node
132-
mv apps/oxlint/src-js/$OXLINT_BIN_SRC_NAME $OXLINT_BIN_NAME
133-
7z a oxlint-${{ matrix.code-target }}.zip $OXLINT_BIN_NAME
134-
135-
OXLS_BIN_NAME=oxc_language_server-${{ matrix.code-target }}
136-
mv target/${{ matrix.target }}/release/oxc_language_server.exe $OXLS_BIN_NAME.exe
137-
7z a $OXLS_BIN_NAME.zip $OXLS_BIN_NAME.exe
125+
- name: Archive oxlint .node binary
126+
uses: ./.github/actions/archive-binary
127+
with:
128+
source_path: apps/oxlint/src-js/oxlint.${{ matrix.code-target }}${{ runner.os == 'Windows' && '-msvc' || '' }}.node
129+
binary_name: oxlint.${{ matrix.code-target }}.node
130+
archive_name: oxlint-${{ matrix.code-target }}
138131

139-
# The binaries are zipped to fix permission loss https://github.com/actions/upload-artifact#permission-loss
140-
- name: Archive Binaries
141-
if: runner.os != 'Windows'
142-
run: |
143-
OXLINT_BIN_NAME=oxlint.${{ matrix.code-target }}.node
144-
mv apps/oxlint/src-js/$OXLINT_BIN_NAME .
145-
tar czf oxlint-${{ matrix.code-target }}.tar.gz $OXLINT_BIN_NAME
132+
- name: Archive Rust binary
133+
uses: ./.github/actions/archive-binary
134+
with:
135+
source_path: target/${{ matrix.target }}/release/oxlint${{ runner.os == 'Windows' && '.exe' || '' }}
136+
binary_name: oxlint-${{ matrix.code-target }}${{ runner.os == 'Windows' && '.exe' || '' }}
137+
archive_name: rust-oxlint-${{ matrix.code-target }}
146138

147-
OXLS_BIN_NAME=oxc_language_server-${{ matrix.code-target }}
148-
mv target/${{ matrix.target }}/release/oxc_language_server $OXLS_BIN_NAME
149-
tar czf $OXLS_BIN_NAME.tar.gz $OXLS_BIN_NAME
139+
- name: Archive language server binary
140+
uses: ./.github/actions/archive-binary
141+
with:
142+
source_path: target/${{ matrix.target }}/release/oxc_language_server${{ runner.os == 'Windows' && '.exe' || '' }}
143+
binary_name: oxc_language_server-${{ matrix.code-target }}${{ runner.os == 'Windows' && '.exe' || '' }}
144+
archive_name: oxc_language_server-${{ matrix.code-target }}
150145

151146
- name: Upload Binary
152147
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
153148
with:
154149
if-no-files-found: error
155150
name: oxlint-${{ matrix.code-target }}
156151
path: |
157-
*.zip
158-
*.tar.gz
152+
oxlint**.zip
153+
oxlint**.tar.gz
154+
oxc_language_server**.zip
155+
oxc_language_server**.tar.gz
156+
157+
# For github release
158+
- name: Upload Binary
159+
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
160+
with:
161+
if-no-files-found: error
162+
name: rust-oxlint-${{ matrix.code-target }}
163+
path: |
164+
rust-oxlint-**.zip
165+
rust-oxlint-**.tar.gz
159166
160167
publish-oxlint:
161168
name: Publish Oxlint
@@ -253,6 +260,8 @@ jobs:
253260

254261
name: Build Oxfmt ${{ matrix.code-target }}
255262
runs-on: ${{ matrix.os }}
263+
env:
264+
TARGET_CC: clang # for mimalloc
256265
defaults:
257266
run:
258267
shell: bash
@@ -277,39 +286,46 @@ jobs:
277286
with:
278287
version: 0.13.0
279288

280-
- name: Build oxfmt
289+
- name: Build oxfmt for node.js
281290
working-directory: apps/oxfmt
282291
run: pnpm run build-napi-release --target ${{ matrix.target }} ${{ matrix.build-oxfmt-args }}
283-
shell: bash
284-
env:
285-
TARGET_CC: clang # for mimalloc
286292

287-
# The binaries are zipped to fix permission loss https://github.com/actions/upload-artifact#permission-loss
288-
- name: Archive Binaries
289-
if: runner.os == 'Windows'
290-
# Windows `.node` files have `-msvc` postfix e.g. `oxfmt.win32-x64-msvc.node`. Remove the postfix.
291-
run: |
292-
OXFMT_BIN_SRC_NAME=oxfmt.${{ matrix.code-target }}-msvc.node
293-
OXFMT_BIN_NAME=oxfmt.${{ matrix.code-target }}.node
294-
mv apps/oxfmt/src-js/$OXFMT_BIN_SRC_NAME $OXFMT_BIN_NAME
295-
7z a oxfmt-${{ matrix.code-target }}.zip $OXFMT_BIN_NAME
293+
- name: Build Rust binary
294+
run: cross build --release -p oxfmt --features allocator --target=${{ matrix.target }}
296295

297296
# The binaries are zipped to fix permission loss https://github.com/actions/upload-artifact#permission-loss
298-
- name: Archive Binaries
299-
if: runner.os != 'Windows'
300-
run: |
301-
OXFMT_BIN_NAME=oxfmt.${{ matrix.code-target }}.node
302-
mv apps/oxfmt/src-js/$OXFMT_BIN_NAME .
303-
tar czf oxfmt-${{ matrix.code-target }}.tar.gz $OXFMT_BIN_NAME
297+
- name: Archive oxfmt .node binary
298+
uses: ./.github/actions/archive-binary
299+
with:
300+
source_path: apps/oxfmt/src-js/oxfmt.${{ matrix.code-target }}${{ runner.os == 'Windows' && '-msvc' || '' }}.node
301+
binary_name: oxfmt.${{ matrix.code-target }}.node
302+
archive_name: oxfmt-${{ matrix.code-target }}
303+
304+
- name: Archive Rust binary
305+
uses: ./.github/actions/archive-binary
306+
with:
307+
source_path: target/${{ matrix.target }}/release/oxfmt${{ runner.os == 'Windows' && '.exe' || '' }}
308+
binary_name: oxfmt-${{ matrix.code-target }}${{ runner.os == 'Windows' && '.exe' || '' }}
309+
archive_name: rust-oxfmt-${{ matrix.code-target }}
304310

305311
- name: Upload Binary
306312
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
307313
with:
308314
if-no-files-found: error
309315
name: oxfmt-${{ matrix.code-target }}
310316
path: |
311-
*.zip
312-
*.tar.gz
317+
oxfmt-**.zip
318+
oxfmt-**.tar.gz
319+
320+
# For github release
321+
- name: Upload Binary
322+
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
323+
with:
324+
if-no-files-found: error
325+
name: rust-oxfmt-${{ matrix.code-target }}
326+
path: |
327+
rust-oxfmt-**.zip
328+
rust-oxfmt-**.tar.gz
313329
314330
publish-oxfmt:
315331
name: Publish Oxfmt
@@ -378,17 +394,16 @@ jobs:
378394
restore-cache: false
379395
tools: cargo-release-oxc
380396

381-
- name: Run
397+
- name: Generate changelog
382398
id: run
383399
run: |
384400
mkdir -p target
385401
cargo release-oxc changelog --release oxfmt --release oxlint
386402
{
387-
echo '# Oxlint'
388-
echo
403+
echo "# Oxlint"
389404
cat ./target/OXLINT_CHANGELOG
390-
echo '# Oxfmt'
391-
echo
405+
echo ""
406+
echo "# Oxfmt"
392407
cat ./target/OXFMT_CHANGELOG
393408
} > ./target/RELEASE_BODY.md
394409
@@ -401,6 +416,19 @@ jobs:
401416
git tag oxlint_v${NEEDS_CHECK_OUTPUTS_OXLINT_VERSION} ${{ github.sha }}
402417
git push origin oxlint_v${NEEDS_CHECK_OUTPUTS_OXLINT_VERSION} oxfmt_v${NEEDS_CHECK_OUTPUTS_OXFMT_VERSION}
403418
419+
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
420+
with:
421+
path: .
422+
pattern: rust-*
423+
merge-multiple: true
424+
425+
- name: Remove rust- prefix from filenames
426+
run: |
427+
for file in rust-*; do
428+
mv "$file" "${file#rust-}"
429+
done
430+
ls
431+
404432
- name: Create GitHub Release
405433
uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
406434
with:
@@ -409,6 +437,10 @@ jobs:
409437
name: oxlint v${{ needs.check.outputs.oxlint_version }} & oxfmt v${{ needs.check.outputs.oxfmt_version }}
410438
tag_name: apps_v${{ needs.check.outputs.oxlint_version }}
411439
target_commitish: ${{ github.sha }}
440+
fail_on_unmatched_files: true
441+
files: |
442+
oxfmt-*
443+
oxlint-*
412444
413445
- name: wait 3 minutes for smoke test
414446
run: sleep 180s
@@ -427,6 +459,9 @@ jobs:
427459
name: Smoke Test ${{ matrix.os }} ${{ matrix.container }}
428460
runs-on: ${{ matrix.os }}
429461
container: ${{ matrix.container }}
462+
defaults:
463+
run:
464+
shell: bash
430465
steps:
431466
- name: Test
432467
shell: bash

apps/oxfmt/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ crate-type = ["lib", "cdylib"]
2020
path = "src/lib.rs"
2121
doctest = false
2222

23+
[[bin]]
24+
name = "oxfmt"
25+
path = "src/main.rs"
26+
test = false
27+
doctest = false
28+
2329
[dependencies]
2430
oxc_allocator = { workspace = true, features = ["pool"] }
2531
oxc_diagnostics = { workspace = true }

apps/oxfmt/src/init.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// Initialize the data which relies on `is_atty` system calls so they don't block subsequent threads.
2+
/// # Panics
3+
pub fn init_miette() {
4+
miette::set_hook(Box::new(|_| Box::new(miette::MietteHandlerOpts::new().build()))).unwrap();
5+
}
6+
7+
/// To debug `oxc_formatter`:
8+
/// `OXC_LOG=oxc_formatter oxfmt`
9+
/// # Panics
10+
pub fn init_tracing() {
11+
use tracing_subscriber::{filter::Targets, prelude::*};
12+
13+
// Usage without the `regex` feature.
14+
// <https://github.com/tokio-rs/tracing/issues/1436#issuecomment-918528013>
15+
tracing_subscriber::registry()
16+
.with(std::env::var("OXC_LOG").map_or_else(
17+
|_| Targets::new(),
18+
|env_var| {
19+
use std::str::FromStr;
20+
Targets::from_str(&env_var).unwrap()
21+
},
22+
))
23+
.with(tracing_subscriber::fmt::layer())
24+
.init();
25+
}

apps/oxfmt/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
mod command;
22
mod format;
3+
mod init;
34
mod reporter;
45
mod result;
56
mod service;
67
mod walk;
78

9+
// Public re-exports for use in main.rs and lib consumers
10+
pub use command::format_command;
11+
pub use format::FormatRunner;
12+
pub use init::{init_miette, init_tracing};
13+
pub use result::CliRunResult;
14+
815
// Only include code to run formatter when the `napi` feature is enabled.
916
#[cfg(feature = "napi")]
1017
mod prettier_plugins;

apps/oxfmt/src/main.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use std::io::BufWriter;
2+
3+
use oxfmt::{CliRunResult, FormatRunner, format_command, init_miette, init_tracing};
4+
5+
fn main() -> CliRunResult {
6+
init_tracing();
7+
init_miette();
8+
9+
// Parse command line arguments from std::env::args()
10+
let command = format_command().run();
11+
12+
command.handle_threads();
13+
14+
// stdio is blocked by LineWriter, use a BufWriter to reduce syscalls.
15+
// See `https://github.com/rust-lang/rust/issues/60673`.
16+
let mut stdout = BufWriter::new(std::io::stdout());
17+
FormatRunner::new(command).run(&mut stdout)
18+
}

apps/oxfmt/src/run.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use napi_derive::napi;
88
use crate::{
99
command::format_command,
1010
format::FormatRunner,
11+
init::{init_miette, init_tracing},
1112
prettier_plugins::{JsFormatEmbeddedCb, create_external_formatter},
1213
result::CliRunResult,
1314
};
@@ -56,27 +57,3 @@ fn format_impl(args: &[String], format_embedded_cb: JsFormatEmbeddedCb) -> CliRu
5657
let mut stdout = BufWriter::new(std::io::stdout());
5758
FormatRunner::new(command).with_external_formatter(Some(external_formatter)).run(&mut stdout)
5859
}
59-
60-
/// Initialize the data which relies on `is_atty` system calls so they don't block subsequent threads.
61-
fn init_miette() {
62-
miette::set_hook(Box::new(|_| Box::new(miette::MietteHandlerOpts::new().build()))).unwrap();
63-
}
64-
65-
/// To debug `oxc_formatter`:
66-
/// `OXC_LOG=oxc_formatter oxfmt`
67-
fn init_tracing() {
68-
use tracing_subscriber::{filter::Targets, prelude::*};
69-
70-
// Usage without the `regex` feature.
71-
// <https://github.com/tokio-rs/tracing/issues/1436#issuecomment-918528013>
72-
tracing_subscriber::registry()
73-
.with(std::env::var("OXC_LOG").map_or_else(
74-
|_| Targets::new(),
75-
|env_var| {
76-
use std::str::FromStr;
77-
Targets::from_str(&env_var).unwrap()
78-
},
79-
))
80-
.with(tracing_subscriber::fmt::layer())
81-
.init();
82-
}

0 commit comments

Comments
 (0)