summaryrefslogtreecommitdiff
path: root/src/publish.rs
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2026-02-15 21:27:00 +0100
committerDawid Rycerz <dawid@rycerz.xyz>2026-02-15 21:27:00 +0100
commitce0dbf6b249956700c6a1705bf4ad85a09d53e8c (patch)
treed7c3236807cfbf75d7f3a355eb5df5a5e2cc4ad7 /src/publish.rs
parent064a1d01c5c14f5ecc032fa9b8346a4a88b893f6 (diff)
feat: witryna 0.2.0HEADv0.2.0main
Switch, cleanup, and status CLI commands. Persistent build state via state.json. Post-deploy hooks on success and failure with WITRYNA_BUILD_STATUS. Dependency diet (axum→tiny_http, clap→argh, tracing→log). Drop built-in rate limiting. Nix flake with NixOS module. Arch Linux PKGBUILD. Centralized version management. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src/publish.rs')
-rw-r--r--src/publish.rs25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/publish.rs b/src/publish.rs
index 338a136..f4862c4 100644
--- a/src/publish.rs
+++ b/src/publish.rs
@@ -1,6 +1,6 @@
use anyhow::{Context as _, Result, bail};
+use log::{debug, info, warn};
use std::path::{Path, PathBuf};
-use tracing::{debug, info};
/// Result of a successful publish operation.
#[derive(Debug)]
@@ -52,9 +52,9 @@ pub async fn publish(
let current_link = site_builds_dir.join("current");
info!(
- source = %source_dir.display(),
- destination = %build_dir.display(),
- "publishing assets"
+ "publishing assets: source={} destination={}",
+ source_dir.display(),
+ build_dir.display()
);
// 3. Create builds directory structure
@@ -76,9 +76,9 @@ pub async fn publish(
atomic_symlink_update(&build_dir, &current_link).await?;
debug!(
- build_dir = %build_dir.display(),
- symlink = %current_link.display(),
- "publish completed"
+ "publish completed: build_dir={} symlink={}",
+ build_dir.display(),
+ current_link.display()
);
Ok(PublishResult {
@@ -109,7 +109,7 @@ async fn copy_dir_contents(src: &Path, dst: &Path) -> Result<()> {
// SEC-002: reject symlinks in build output to prevent symlink attacks
let metadata = tokio::fs::symlink_metadata(&entry_path).await?;
if metadata.file_type().is_symlink() {
- tracing::warn!(path = %entry_path.display(), "skipping symlink in build output");
+ warn!("skipping symlink in build output: {}", entry_path.display());
continue;
}
@@ -144,7 +144,11 @@ async fn copy_dir_contents(src: &Path, dst: &Path) -> Result<()> {
/// 2. Rename temp to final: {`link_path}.tmp` -> {`link_path`}
///
/// The rename operation is atomic on POSIX filesystems.
-async fn atomic_symlink_update(target: &Path, link_path: &Path) -> Result<()> {
+///
+/// # Errors
+///
+/// Returns an error if the temporary symlink cannot be created or the atomic rename fails.
+pub async fn atomic_symlink_update(target: &Path, link_path: &Path) -> Result<()> {
let temp_link = link_path.with_extension("tmp");
// Remove any stale temp symlink from previous failed attempts
@@ -168,11 +172,10 @@ async fn atomic_symlink_update(target: &Path, link_path: &Path) -> Result<()> {
mod tests {
use super::*;
use crate::test_support::{cleanup, temp_dir};
- use chrono::Utc;
use tokio::fs;
fn test_timestamp() -> String {
- Utc::now().format("%Y%m%d-%H%M%S-%f").to_string()
+ crate::time::format_build_timestamp(std::time::SystemTime::now())
}
#[tokio::test]