mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 09:41:04 +01:00
Address paperclip page publish review
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
f3c38419a2
commit
d7e0eaf764
2 files changed
+94
-7
No files matched your search
@@ -318,6 +318,10 @@ fi
|
||||
prefix="$(join_prefix "$default_prefix" "$slug")"
|
||||
target_exists=0
|
||||
|
||||
if [[ "$update" == "1" ]]; then
|
||||
assert_update_ownership "$source_dir" "$bucket" "$prefix"
|
||||
fi
|
||||
|
||||
if [[ "$dry_run" == "0" ]]; then
|
||||
if object_exists "$bucket" "$prefix"; then
|
||||
target_exists=1
|
||||
@@ -343,10 +347,6 @@ if [[ "$dry_run" == "0" ]]; then
|
||||
|
||||
[[ "$target_exists" == "0" ]] || die "could not find an unused generated slug after 5 attempts"
|
||||
fi
|
||||
|
||||
if [[ "$target_exists" == "1" && "$update" == "1" ]]; then
|
||||
assert_update_ownership "$source_dir" "$bucket" "$prefix"
|
||||
fi
|
||||
fi
|
||||
|
||||
url="${base_url}/${prefix}"
|
||||
@@ -373,11 +373,11 @@ aws_cli s3 sync "$source_dir/" "s3://$bucket/$prefix" \
|
||||
--cache-control 'public,max-age=60' \
|
||||
--only-show-errors
|
||||
|
||||
curl -fsSIL --max-time 20 "$url" >/dev/null
|
||||
|
||||
source_hash="$(compute_source_hash "$source_dir")"
|
||||
write_state "$source_dir" "$bucket" "$prefix" "$slug" "$url" "$base_url" "$source_hash"
|
||||
|
||||
curl -fsSIL --max-time 20 "$url" >/dev/null
|
||||
|
||||
cat <<EOF
|
||||
paperclip-page published
|
||||
mode: $mode
|
||||
|
||||
@@ -1,24 +1,46 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import {
|
||||
chmodSync,
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
mkdtempSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
statSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import test from "node:test";
|
||||
import { after, test } from "node:test";
|
||||
|
||||
const scriptPath = join(dirname(fileURLToPath(import.meta.url)), "publish.sh");
|
||||
const tempDirs = new Set();
|
||||
|
||||
after(() => {
|
||||
for (const dir of tempDirs) {
|
||||
rmSync(dir, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
function createSite(name = "paperclip-page-test") {
|
||||
const siteDir = mkdtempSync(join(tmpdir(), `${name}-`));
|
||||
tempDirs.add(siteDir);
|
||||
writeFileSync(join(siteDir, "index.html"), "<!doctype html><title>Paperclip</title>\n");
|
||||
return siteDir;
|
||||
}
|
||||
|
||||
function writeExecutable(path, body) {
|
||||
writeFileSync(path, body, { mode: 0o755 });
|
||||
chmodSync(path, 0o755);
|
||||
}
|
||||
|
||||
function writeState(siteDir, state) {
|
||||
mkdirSync(join(siteDir, ".paperclip-page"), { recursive: true });
|
||||
writeFileSync(join(siteDir, ".paperclip-page", "state.json"), `${JSON.stringify(state)}\n`);
|
||||
}
|
||||
|
||||
function runPublish(args, env = {}) {
|
||||
try {
|
||||
return {
|
||||
@@ -73,6 +95,24 @@ test("dry run normalizes a safe default prefix", () => {
|
||||
assert.match(result.output, /^url: https:\/\/pages\.example\.test\/reports\/launches\/demo-page\/$/m);
|
||||
});
|
||||
|
||||
test("dry run update requires matching local ownership state", () => {
|
||||
const siteDir = createSite();
|
||||
const missingState = runPublish([siteDir, "--slug", "demo-page", "--update", "--dry-run"]);
|
||||
|
||||
assert.notEqual(missingState.status, 0);
|
||||
assert.match(missingState.output, /requires ownership state/);
|
||||
|
||||
writeState(siteDir, {
|
||||
bucket: "paperclip-pages-test",
|
||||
prefix: "demo-page/",
|
||||
});
|
||||
|
||||
const result = runPublish([siteDir, "--slug", "demo-page", "--update", "--dry-run"]);
|
||||
|
||||
assert.equal(result.status, 0);
|
||||
assert.match(result.output, /^mode: update$/m);
|
||||
});
|
||||
|
||||
test("rejects nested slugs", () => {
|
||||
const result = runPublish([createSite(), "--slug", "nested/path", "--dry-run"]);
|
||||
|
||||
@@ -90,3 +130,50 @@ test("rejects hidden files in the source tree", () => {
|
||||
assert.notEqual(result.status, 0);
|
||||
assert.match(result.output, /hidden files and dot paths are not allowed/);
|
||||
});
|
||||
|
||||
test("live publish writes state before URL verification", () => {
|
||||
const siteDir = createSite();
|
||||
const binDir = mkdtempSync(join(tmpdir(), "paperclip-page-bin-"));
|
||||
tempDirs.add(binDir);
|
||||
|
||||
writeExecutable(
|
||||
join(binDir, "aws"),
|
||||
`#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
while [[ "$1" == "--region" || "$1" == "--profile" ]]; do
|
||||
shift 2
|
||||
done
|
||||
if [[ "$1" == "s3api" ]]; then
|
||||
echo "None"
|
||||
exit 0
|
||||
fi
|
||||
if [[ "$1" == "s3" && "$2" == "sync" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
echo "unexpected aws call: $*" >&2
|
||||
exit 1
|
||||
`,
|
||||
);
|
||||
writeExecutable(
|
||||
join(binDir, "curl"),
|
||||
`#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
echo "simulated CloudFront propagation miss" >&2
|
||||
exit 22
|
||||
`,
|
||||
);
|
||||
|
||||
const result = runPublish([siteDir, "--slug", "demo-page"], {
|
||||
AWS_REGION: "us-east-1",
|
||||
PATH: `${binDir}:${process.env.PATH}`,
|
||||
});
|
||||
|
||||
assert.notEqual(result.status, 0);
|
||||
assert.match(result.output, /simulated CloudFront propagation miss/);
|
||||
assert.equal(existsSync(join(siteDir, ".paperclip-page", "state.json")), true);
|
||||
|
||||
const state = JSON.parse(readFileSync(join(siteDir, ".paperclip-page", "state.json"), "utf8"));
|
||||
assert.equal(state.bucket, "paperclip-pages-test");
|
||||
assert.equal(state.prefix, "demo-page/");
|
||||
assert.equal(state.url, "https://pages.example.test/demo-page/");
|
||||
});
|
||||
Reference in new issue
Block a user