Skip to content

Commit f5ec360

Browse files
committed
publisher script for testers
1 parent b6b255d commit f5ec360

3 files changed

Lines changed: 134 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Publish binary
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
inputs:
9+
tag:
10+
description: 'Release tag'
11+
required: true
12+
type: string
13+
14+
env:
15+
CARGO_TERM_COLOR: always
16+
17+
jobs:
18+
build_n_publish:
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
os: [ubuntu-latest, macos-latest, windows-latest]
23+
24+
runs-on: ${{ matrix.os }}
25+
26+
steps:
27+
- uses: actions/checkout@v4
28+
- uses: dtolnay/rust-toolchain@stable
29+
- name: Build
30+
if: ${{ !cancelled() }}
31+
run: cargo build --release --verbose --examples --all-features
32+
- name: Prepare for publish
33+
if: ${{ !cancelled() }}
34+
shell: bash
35+
run: |
36+
mkdir -p mypubdir4
37+
if [[ "${{ matrix.os }}" == "windows-latest" ]]; then
38+
powershell -Command "(Get-Item target/release/examples/wintun.dll).LastWriteTime = Get-Date"
39+
powershell Compress-Archive -Path target/release/examples/tun.exe, README.md, target/release/examples/wintun.dll -DestinationPath mypubdir4/ipstack-${{ matrix.os }}.zip
40+
else
41+
zip -j mypubdir4/ipstack-${{ matrix.os }}.zip target/release/examples/tun README.md
42+
fi
43+
- name: Publish
44+
if: ${{ !cancelled() }}
45+
uses: softprops/action-gh-release@v1
46+
env:
47+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48+
with:
49+
files: mypubdir4/*
50+
tag_name: ${{ github.event.inputs.tag || github.ref }}
51+
52+
- name: Abort on error
53+
if: ${{ failure() }}
54+
run: echo "Some of jobs failed" && false

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ udp-stream = { version = "0.0", default-features = false }
3838
[target.'cfg(target_os = "windows")'.dev-dependencies]
3939
wintun = { version = "0.5", default-features = false }
4040

41+
[build-dependencies]
42+
serde_json = "1"
43+
4144
[profile.release]
4245
opt-level = 's' # Optimize for size (with loop vectorization enabled).
4346
lto = true # Enable Link Time Optimization

build.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
fn main() -> Result<(), Box<dyn std::error::Error>> {
2+
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_else(|_| "unknown".to_string());
3+
4+
if target_os == "windows" {
5+
let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR")?);
6+
let profile = std::env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
7+
8+
let Ok(cargo_target_dir) = extract_matching_parent_dir(&out_dir, &profile) else {
9+
println!("cargo:warning=Could not find target directory");
10+
return Ok(());
11+
};
12+
// The wintun crate's root directory
13+
let crate_dir = get_crate_dir("wintun")?;
14+
15+
// The path to the DLL file, relative to the crate root, depending on the target architecture
16+
let dll_path = get_wintun_bin_relative_path()?;
17+
let src_path = crate_dir.join(dll_path);
18+
19+
let dst_path = cargo_target_dir.join("examples/wintun.dll");
20+
21+
// Copy to the target directory
22+
std::fs::copy(src_path, &dst_path)?;
23+
24+
// Set the modified time to the current time, or the publishing process will fail.
25+
let file = std::fs::OpenOptions::new().write(true).open(&dst_path)?;
26+
file.set_modified(std::time::SystemTime::now())?;
27+
}
28+
Ok(())
29+
}
30+
31+
fn extract_matching_parent_dir<P: AsRef<std::path::Path>>(path: P, match_name: &str) -> std::io::Result<std::path::PathBuf> {
32+
let target_dir = std::path::Path::new(path.as_ref())
33+
.ancestors()
34+
.find(|p| p.file_name().map(|n| *n == *match_name).unwrap_or(false))
35+
.ok_or(std::io::Error::new(
36+
std::io::ErrorKind::NotFound,
37+
format!("No parent directory matching '{match_name}'"),
38+
))?;
39+
Ok(target_dir.to_path_buf())
40+
}
41+
42+
fn get_wintun_bin_relative_path() -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
43+
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH")?;
44+
45+
let dll_path = match target_arch.as_str() {
46+
"x86" => "wintun/bin/x86/wintun.dll",
47+
"x86_64" => "wintun/bin/amd64/wintun.dll",
48+
"arm" => "wintun/bin/arm/wintun.dll",
49+
"aarch64" => "wintun/bin/arm64/wintun.dll",
50+
_ => return Err("Unsupported architecture".into()),
51+
};
52+
53+
Ok(dll_path.into())
54+
}
55+
56+
fn get_crate_dir(crate_name: &str) -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
57+
let output = std::process::Command::new("cargo")
58+
.arg("metadata")
59+
.arg("--format-version=1")
60+
.output()?;
61+
62+
let metadata = serde_json::from_slice::<serde_json::Value>(&output.stdout)?;
63+
let packages = metadata["packages"].as_array().ok_or("packages")?;
64+
65+
let mut crate_dir = None;
66+
67+
for package in packages {
68+
let name = package["name"].as_str().ok_or("name")?;
69+
if name == crate_name {
70+
let path = package["manifest_path"].as_str().ok_or("manifest_path")?;
71+
let path = std::path::PathBuf::from(path);
72+
crate_dir = Some(path.parent().ok_or("parent")?.to_path_buf());
73+
break;
74+
}
75+
}
76+
Ok(crate_dir.ok_or("crate_dir")?)
77+
}

0 commit comments

Comments
 (0)