diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..2ec7c5044 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,62 @@ +# Based on ripgrep's release action: +# https://github.com/BurntSushi/ripgrep/blob/master/.github/workflows/release.yml + +name: Build Release Binaries +on: + release: + types: [created] + +jobs: + build-release: + name: build-release + runs-on: ${{ matrix.os }} + strategy: + matrix: + build: [linux, macos, win-msvc] + include: + - build: linux + os: ubuntu-22.04 + target: x86_64-unknown-linux-gnu + - build: macos + os: macos-12 + target: x86_64-apple-darwin + - build: win-msvc + os: windows-2022 + target: x86_64-pc-windows-msvc + + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + + - name: Build release binary + run: cargo build -p typst-cli --release + + - name: Strip binary (Linux and macOS) + if: matrix.build == 'linux' || matrix.build == 'macos' + run: strip "target/release/typst" + + - name: Build archive + shell: bash + run: | + directory="typst-${{ matrix.target }}" + mkdir "$directory" + cp {README.md,LICENSE,NOTICE} "$directory/" + if [ "${{ matrix.os }}" = "windows-2022" ]; then + cp "target/release/typst.exe" "$directory/" + 7z a "$directory.zip" "$directory" + echo "ASSET=$directory.zip" >> $GITHUB_ENV + else + cp "target/release/typst" "$directory/" + tar czf "$directory.tar.gz" "$directory" + echo "ASSET=$directory.tar.gz" >> $GITHUB_ENV + fi + + - name: Upload release archive + uses: actions/upload-release-asset@v1.0.2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ${{ env.ASSET }} + asset_name: ${{ env.ASSET }} + asset_content_type: application/octet-stream diff --git a/cli/build.rs b/cli/build.rs new file mode 100644 index 000000000..f7b70e7f8 --- /dev/null +++ b/cli/build.rs @@ -0,0 +1,9 @@ +use std::error::Error; +use std::process::Command; + +fn main() -> Result<(), Box> { + let output = Command::new("git").args(&["rev-parse", "HEAD"]).output()?; + let hash = std::str::from_utf8(&output.stdout)?; + println!("cargo:rustc-env=TYPST_HASH={}", &hash[..8]); + Ok(()) +} diff --git a/cli/src/main.rs b/cli/src/main.rs index b7cac1eea..40d1a7802 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -55,6 +55,7 @@ ARGS: OPTIONS: -h, --help Print this help + -V, --version Print the CLI's version -w, --watch Watch the inputs and recompile on changes --root Configure the root for absolute paths @@ -94,6 +95,10 @@ fn main() { /// Parse command line arguments. fn parse_args() -> StrResult { let mut args = Arguments::from_env(); + if args.contains(["-V", "--version"]) { + print_version(); + } + let help = args.contains(["-h", "--help"]); let command = if args.contains("--fonts") { @@ -144,11 +149,17 @@ fn parse_input_output(args: &mut Arguments, ext: &str) -> StrResult<(PathBuf, Pa } /// Print a help string and quit. -fn print_help(help: &'static str) { +fn print_help(help: &'static str) -> ! { print!("{help}"); std::process::exit(0); } +/// Print the version hash and quit. +fn print_version() -> ! { + println!("typst {}", env!("TYPST_HASH")); + std::process::exit(0); +} + /// Print an application-level error (independent from a source file). fn print_error(msg: &str) -> io::Result<()> { let mut w = StandardStream::stderr(ColorChoice::Always);