Skip to content

Commit 55de359

Browse files
committed
chore: init workflow
1 parent c2263d2 commit 55de359

4 files changed

Lines changed: 215 additions & 0 deletions

File tree

.github/workflows/release_rust.yml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Release Rust Crates
2+
3+
on:
4+
push:
5+
tags:
6+
- 'loro-crdt@*'
7+
8+
jobs:
9+
release:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
with:
14+
fetch-depth: 0
15+
16+
- name: Install Deno
17+
uses: denoland/setup-deno@v2
18+
with:
19+
deno-version: v2.x
20+
21+
- name: Install Rust
22+
uses: dtolnay/rust-toolchain@stable
23+
with:
24+
components: rustfmt
25+
26+
- name: Extract version
27+
id: version
28+
run: |
29+
VERSION=${GITHUB_REF#refs/tags/loro-crdt@}
30+
echo "version=$VERSION"
31+
echo "version=$VERSION" >> $GITHUB_OUTPUT
32+
33+
- name: Create Release PR
34+
run: |
35+
cargo install cargo-release
36+
git checkout -b release-${{ steps.version.outputs.version }}
37+
# Run cargo release and capture the output
38+
echo "Starting release process..."
39+
echo "Running deno script with version: ${{ steps.version.outputs.version }}"
40+
deno run -A scripts/cargo-release-cli.ts ${{ steps.version.outputs.version }} 2>&1 | tee debug_output.log
41+
RELEASE_OUTPUT=$(tail -n 1 debug_output.log)
42+
echo "Full debug output:"
43+
cat debug_output.log
44+
echo "Last line output: $RELEASE_OUTPUT"
45+
echo "excluded_flags=$RELEASE_OUTPUT"
46+
echo "excluded_flags=$RELEASE_OUTPUT" >> $GITHUB_OUTPUT
47+
git config --global user.name "GitHub Actions"
48+
git config --global user.email "actions@github.com"
49+
git add .
50+
git commit -m "chore: bump version to ${{ steps.version.outputs.version }}"
51+
git push origin HEAD:refs/heads/release-${{ steps.version.outputs.version }}
52+
53+
- name: Create Pull Request
54+
uses: peter-evans/create-pull-request@v5
55+
with:
56+
token: ${{ secrets.GITHUB_TOKEN }}
57+
title: "Release v${{ steps.version.outputs.version }}"
58+
body: |
59+
This PR is automatically created to release version ${{ steps.version.outputs.version }}.
60+
Please review the changes and merge to trigger the release.
61+
branch: release-${{ steps.version.outputs.version }}
62+
base: test-rust-ci
63+
64+
65+
66+
publish:
67+
needs: release
68+
runs-on: ubuntu-latest
69+
if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true
70+
steps:
71+
- uses: actions/checkout@v4
72+
73+
- name: Install Rust
74+
uses: dtolnay/rust-toolchain@stable
75+
with:
76+
components: rustfmt
77+
78+
- name: Extract version
79+
id: version
80+
run: |
81+
VERSION=${GITHUB_REF#refs/tags/loro-crdt@}
82+
echo "version=$VERSION" >> $GITHUB_OUTPUT
83+
84+
- name: Publish to crates.io
85+
env:
86+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
87+
run: |
88+
cargo release publish --workspace ${{ needs.release.outputs.excluded_flags }} --execute --no-confirm
89+
cargo release tag --workspace ${{ needs.release.outputs.excluded_flags }} --execute --no-confirm
90+
git push --tags

crates/loro-ffi/src/doc.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,10 @@ impl LoroDoc {
854854
pub fn delete_root_container(&self, cid: ContainerID) {
855855
self.doc.delete_root_container(cid.into());
856856
}
857+
858+
fn new_api(&self) {
859+
println!("new api");
860+
}
857861
}
858862

859863
pub trait ChangeAncestorsTraveler: Sync + Send {

crates/loro-internal/src/loro.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,10 @@ impl LoroDoc {
19151915
.hide_empty_root_containers
19161916
.store(hide, std::sync::atomic::Ordering::Relaxed);
19171917
}
1918+
1919+
fn new_api(&self) {
1920+
println!("new api");
1921+
}
19181922
}
19191923

19201924
// FIXME: PERF: This method is quite slow because it iterates all the changes

scripts/cargo-release-cli.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env -S deno run --allow-run --allow-env
2+
3+
import { defineCommand, runMain } from "npm:citty";
4+
import { runSyncLoroVersion } from "./sync-loro-version.ts";
5+
6+
async function runCargoRelease(version: string): Promise<string> {
7+
const process = new Deno.Command("cargo", {
8+
args: ["release", "version", "--workspace", version],
9+
});
10+
const output = await process.output();
11+
return new TextDecoder().decode(output.stderr);
12+
}
13+
14+
function parseNoChangesCrates(output: string): string[] {
15+
const lines = output.split("\n");
16+
const noChangesCrates: string[] = [];
17+
18+
for (const line of lines) {
19+
if (line.includes("despite no changes made since tag")) {
20+
const match = line.match(/updating ([^ ]+) to/);
21+
if (match) {
22+
noChangesCrates.push(match[1]);
23+
}
24+
}
25+
}
26+
27+
return noChangesCrates;
28+
}
29+
30+
function generateOptimizedCommand(
31+
version: string,
32+
excludedCrates: string[],
33+
): string {
34+
const excludeFlags = excludedCrates.map((crate) => `--exclude ${crate}`).join(
35+
" ",
36+
);
37+
return `cargo release version --workspace ${version} ${excludeFlags} --execute --no-confirm`;
38+
}
39+
40+
function isValidVersion(version: string): boolean {
41+
// Matches format like 1.2.3
42+
return /^\d+\.\d+\.\d+$/.test(version);
43+
}
44+
45+
const main = defineCommand({
46+
meta: {
47+
name: "cargo-release",
48+
version: "1.0.0",
49+
description: "Bump version with optimized excludes",
50+
},
51+
args: {
52+
version: {
53+
type: "positional",
54+
description: "Version to bump to (format: x.y.z)",
55+
required: true,
56+
},
57+
},
58+
async run({ args }) {
59+
const version = args.version;
60+
// console.log(version);
61+
62+
if (!isValidVersion(version)) {
63+
throw new Error("Version must be in format x.y.z (e.g., 1.2.3)");
64+
}
65+
// TODO: for test now
66+
// runSyncLoroVersion(version);
67+
const output = await runCargoRelease(version);
68+
const noChangesCrates = parseNoChangesCrates(output);
69+
console.log("noChangesCrates:", noChangesCrates);
70+
const excludeFlags = noChangesCrates.map((crate) => `--exclude ${crate}`).join(
71+
" ",
72+
);
73+
// console.log("\n Run command to bump version:");
74+
// console.log(generateOptimizedCommand(version, noChangesCrates));
75+
// Execute the command to bump version
76+
const cmd = generateOptimizedCommand(version, noChangesCrates);
77+
console.log(cmd);
78+
const p1 = new Deno.Command("cargo", {
79+
args: cmd.split(" ").slice(1),
80+
});
81+
const p1Output = await p1.output();
82+
console.log(new TextDecoder().decode(p1Output.stderr));
83+
console.log("done");
84+
console.log("cargo release version");
85+
// const bumpOutput = await bumpProcess.output();
86+
// console.log(new TextDecoder().decode(bumpOutput.stderr));
87+
const bumpProcess = new Deno.Command("cargo", {
88+
args: [
89+
"release",
90+
"version",
91+
"--workspace",
92+
version,
93+
...excludeFlags.split(" "),
94+
"--execute",
95+
"--no-confirm"
96+
]
97+
});
98+
const bumpOutput = await bumpProcess.output();
99+
console.log(new TextDecoder().decode(bumpOutput.stderr));
100+
console.log(excludeFlags);
101+
// console.log("2. Then Commit the changes");
102+
// console.log("3. Run command to publish:");
103+
// console.log(
104+
// `cargo release publish--workspace ${ excludeFlags }`,
105+
// );
106+
// console.log("4. Tag:");
107+
// console.log(
108+
// `cargo release tag--workspace ${ excludeFlags }`,
109+
// );
110+
// console.log("5. Push:");
111+
// console.log(
112+
// `git push--tags && git push`,
113+
// );
114+
},
115+
});
116+
117+
runMain(main);

0 commit comments

Comments
 (0)