BlueGit

golden-age paperdoll-renderer

Files

paperdoll-renderer / tests / release_publish.rs

release_publish.rs

release_publish.rs 4.1 KiB Download Raw
1//! The tag publish step must not recreate the git tag and must not send
2//! replace. BlueGit has no attach-to-existing-tag route; the script refuses
3//! the create-release call instead of issuing it.
4
5use std::fs;
6use std::os::unix::fs::PermissionsExt;
7use std::path::PathBuf;
8use std::process::Command;
9
10fn repo_root() -> PathBuf {
11 PathBuf::from(env!("CARGO_MANIFEST_DIR"))
12}
13
14fn path_prefix_env(prefix: &std::path::Path) -> std::ffi::OsString {
15 let mut path = std::ffi::OsString::from(prefix);
16 path.push(":");
17 path.push(std::env::var_os("PATH").unwrap_or_default());
18 path
19}
20
21fn install_curl_trap(dir: &std::path::Path) -> PathBuf {
22 let curl = dir.join("curl");
23 fs::write(
24 &curl,
25 "#!/bin/sh\nprintf '%s\\n' \"$*\" >> \"${CURL_TRAP_LOG:?}\"\nexit 0\n",
26 )
27 .unwrap();
28 let mut permissions = fs::metadata(&curl).unwrap().permissions();
29 permissions.set_mode(0o755);
30 fs::set_permissions(&curl, permissions).unwrap();
31 curl
32}
33
34fn executable_lines(script: &str) -> String {
35 script
36 .lines()
37 .map(str::trim)
38 .filter(|line| !line.is_empty() && !line.starts_with('#'))
39 .collect::<Vec<_>>()
40 .join("\n")
41}
42
43#[test]
44fn tag_publish_does_not_call_create_release_or_send_replace() {
45 let dir = std::env::temp_dir().join(format!("paperdoll-release-trap-{}", std::process::id()));
46 let _ = fs::remove_dir_all(&dir);
47 fs::create_dir_all(&dir).unwrap();
48 let log = dir.join("curl.log");
49 install_curl_trap(&dir);
50
51 let output = Command::new("bash")
52 .arg(repo_root().join("scripts/ci/release.sh"))
53 .env("PATH", path_prefix_env(&dir))
54 .env("CURL_TRAP_LOG", &log)
55 .env("CI_API_URL", "https://git.example.invalid/api/v1")
56 .env("CI_JOB_TOKEN", "bgj_test_token_not_secret")
57 .env("CI_COMMIT_SHA", "0123456789abcdef0123456789abcdef01234567")
58 .env("CI_PROJECT_PATH", "golden-age/paperdoll-renderer")
59 .env("CI_COMMIT_TAG", "v0.1.0")
60 .env_remove("PACKAGE_VERSION")
61 .output()
62 .unwrap();
63
64 let stderr = String::from_utf8_lossy(&output.stderr);
65 let stdout = String::from_utf8_lossy(&output.stdout);
66 assert_eq!(
67 output.status.code(),
68 Some(3),
69 "stdout:\n{stdout}\nstderr:\n{stderr}"
70 );
71 assert!(
72 stderr.contains("release-blocked: no-attach-endpoint"),
73 "{stderr}"
74 );
75 assert!(
76 !log.exists(),
77 "curl was invoked:\n{}",
78 fs::read_to_string(&log).unwrap_or_default()
79 );
80 let script = fs::read_to_string(repo_root().join("scripts/ci/release.sh")).unwrap();
81 let executable = executable_lines(&script);
82 assert!(
83 !executable.contains("curl"),
84 "executable release script must not call curl:\n{executable}"
85 );
86 assert!(
87 !executable.contains("replace"),
88 "executable release script must not send replace:\n{executable}"
89 );
90 let _ = fs::remove_dir_all(&dir);
91}
92
93#[test]
94fn tag_publish_still_rejects_a_non_semver_tag_before_the_api_block() {
95 let dir =
96 std::env::temp_dir().join(format!("paperdoll-release-trap-bad-{}", std::process::id()));
97 let _ = fs::remove_dir_all(&dir);
98 fs::create_dir_all(&dir).unwrap();
99 let log = dir.join("curl.log");
100 install_curl_trap(&dir);
101 let output = Command::new("bash")
102 .arg(repo_root().join("scripts/ci/release.sh"))
103 .env("PATH", path_prefix_env(&dir))
104 .env("CURL_TRAP_LOG", &log)
105 .env("CI_API_URL", "https://git.example.invalid/api/v1")
106 .env("CI_JOB_TOKEN", "bgj_test_token_not_secret")
107 .env("CI_COMMIT_SHA", "0123456789abcdef0123456789abcdef01234567")
108 .env("CI_PROJECT_PATH", "golden-age/paperdoll-renderer")
109 .env("CI_COMMIT_TAG", "not-a-version")
110 .env_remove("PACKAGE_VERSION")
111 .output()
112 .unwrap();
113 assert_ne!(output.status.code(), Some(0));
114 assert_ne!(output.status.code(), Some(3));
115 let stderr = String::from_utf8_lossy(&output.stderr);
116 assert!(stderr.contains("package version must be X.Y.Z"), "{stderr}");
117 assert!(!log.exists(), "curl was invoked for an invalid tag");
118 let _ = fs::remove_dir_all(&dir);
119}