Skip to content

Commit d5eaa93

Browse files
committed
release(v0.2.3): harden GitHub PR receipt workflows
1 parent 121634e commit d5eaa93

20 files changed

Lines changed: 1037 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## v0.2.3 - 05/12/2026
4+
5+
- Added a guarded GitHub PR helper in the web UI for previewing and explicitly posting/updating a compact receipt comment from the current receipt.
6+
- Added web UI copy helpers for local GitHub dry runs, CI auto-comment commands, and a ready-to-use GitHub Actions workflow snippet.
7+
- Improved `runglass github detect` with PR URL, token readiness, and next-step diagnostics.
8+
- Made `runglass github comment --auto` print the detected GitHub context before posting.
9+
- Hardened GitHub docs around web UI behavior, token handling, and PR comment permissions.
10+
311
## v0.2.2 - 05/11/2026
412

513
- Added `runglass validate [latest|receipt-id|receipt.json|receipt-dir]` to check receipt JSON, CI artifact layout, and revert snapshot availability.

Cargo.lock

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ members = [
77
resolver = "2"
88

99
[workspace.package]
10-
version = "0.2.2"
10+
version = "0.2.3"
1111
edition = "2021"
1212
license = "MIT"
1313
repository = "https://github.com/error311/runglass"

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ runglass github comment --receipt runglass-receipt/receipt.json --auto
229229

230230
Authentication is read from `GITHUB_TOKEN`, `GH_TOKEN`, or `gh auth token`. RunGlass does not accept GitHub tokens as CLI arguments, so tokens do not need to appear in shell history or process listings. Tokens are not written into receipt artifacts. The GitHub token needs permission to write issue or pull request comments.
231231

232+
The local web UI also includes a guarded GitHub PR receipt helper for saved receipts. It can preview the exact PR comment, copy local/CI commands, copy a GitHub Actions workflow snippet, and post or update the PR comment after explicit confirmation. Tokens are still resolved server-side only; the browser never asks for or stores a GitHub token.
233+
232234
See [GitHub integration docs](docs/github-integration.md) for workflow examples, API behavior, and token permissions.
233235

234236
## CI Receipts

crates/runglass-cli/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ description = "Run one command and get a live receipt of what happened."
1212
anyhow = "1.0"
1313
chrono = "0.4"
1414
clap = { version = "4.5", features = ["derive"] }
15-
runglass-core = { path = "../runglass-core", version = "0.2.2" }
16-
runglass-web = { path = "../runglass-web", version = "0.2.2" }
15+
runglass-core = { path = "../runglass-core", version = "0.2.3" }
16+
runglass-web = { path = "../runglass-web", version = "0.2.3" }
1717
serde_json = "1.0"
1818
ureq = { version = "2.12", features = ["json"] }
1919

crates/runglass-cli/src/github.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct RepoParts {
3333

3434
pub(crate) fn detect_command(repo: Option<String>, pr: Option<u64>) -> Result<()> {
3535
let context = detect_context(repo, pr)?;
36+
let token = token_source();
3637
println!("GitHub context");
3738
print_detected("Repository", context.repo.as_deref());
3839
print_detected(
@@ -41,7 +42,24 @@ pub(crate) fn detect_command(repo: Option<String>, pr: Option<u64>) -> Result<()
4142
);
4243
print_detected("Commit SHA", context.sha.as_deref());
4344
print_detected("Run URL", context.run_url.as_deref());
44-
print_detected("Token", token_source().as_deref());
45+
print_detected("Token", token.as_deref());
46+
if let Some(url) = pr_url(context.repo.as_deref(), context.pr) {
47+
print_detected("PR URL", Some(url.as_str()));
48+
}
49+
let ready = context.repo.is_some() && context.pr.is_some() && token.is_some();
50+
println!(
51+
"Comment readiness\t{}",
52+
if ready {
53+
"ready to post or update a PR comment"
54+
} else {
55+
"needs repository, pull request, and token"
56+
}
57+
);
58+
if !ready {
59+
println!(
60+
"Next\tpass --repo owner/name and --pr <number>, and set GITHUB_TOKEN/GH_TOKEN or run gh auth login"
61+
);
62+
}
4563
Ok(())
4664
}
4765

@@ -70,6 +88,19 @@ pub(crate) fn comment_command(report: &RunReport, options: GithubCommentOptions)
7088

7189
let token = resolve_token()?;
7290
let client = GithubApiClient::new(options.api_url.as_deref().unwrap_or(DEFAULT_API_URL), token);
91+
if options.auto {
92+
println!(
93+
"Detected GitHub context: {}/{}#{}{}",
94+
repo.owner,
95+
repo.repo,
96+
pr,
97+
context
98+
.run_url
99+
.as_deref()
100+
.map(|url| format!(" ({url})"))
101+
.unwrap_or_default()
102+
);
103+
}
73104
match client.find_marker_comment(&repo, pr)? {
74105
Some(comment_id) => {
75106
client.update_comment(&repo, comment_id, &body)?;
@@ -90,6 +121,10 @@ pub(crate) fn comment_command(report: &RunReport, options: GithubCommentOptions)
90121
Ok(())
91122
}
92123

124+
fn pr_url(repo: Option<&str>, pr: Option<u64>) -> Option<String> {
125+
Some(format!("https://github.com/{}/pull/{}", repo?, pr?))
126+
}
127+
93128
fn detect_context(repo: Option<String>, pr: Option<u64>) -> Result<GithubContext> {
94129
let repo = repo
95130
.or_else(|| env::var("GITHUB_REPOSITORY").ok())

crates/runglass-web/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ description = "Embedded local web UI and export renderer for RunGlass receipts."
1111
[dependencies]
1212
anyhow = "1.0"
1313
chrono = { version = "0.4", features = ["serde"] }
14-
runglass-core = { path = "../runglass-core", version = "0.2.2" }
14+
runglass-core = { path = "../runglass-core", version = "0.2.3" }
1515
serde_json = "1.0"
1616
tiny_http = "0.12"
17+
ureq = { version = "2.12", features = ["json"] }
1718
webbrowser = "1.0"

0 commit comments

Comments
 (0)