刘光辉
12 小时以前 0dfe84494048ce27ba8449831782128412d3eb13
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env sh
set -eu
 
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
PLUGIN_DIR=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd -P)
DIST_DIR="$PLUGIN_DIR/dist"
CONTRACT="$SCRIPT_DIR/production-contract.mjs"
STAGING=''
TARGET_PARENT=''
 
cleanup() {
  status=$?
  trap - EXIT HUP INT TERM
  if [ -n "$STAGING" ] && [ -n "$TARGET_PARENT" ]; then
    case "$STAGING" in
      "$TARGET_PARENT"/.eln-template-annotator.staging.*)
        if [ -d "$STAGING" ] && ! rm -rf "$STAGING"; then
          printf '%s\n' "Failed to clean release staging: $STAGING" >&2
          [ "$status" -ne 0 ] || status=1
        fi
        ;;
      *)
        printf '%s\n' 'Refusing to clean an unverified release staging path' >&2
        [ "$status" -ne 0 ] || status=1
        ;;
    esac
  fi
  exit "$status"
}
 
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
 
fail() {
  printf '%s\n' "$1" >&2
  exit "${2:-1}"
}
 
for command in diff mktemp node; do
  command -v "$command" >/dev/null 2>&1 || fail "$command is required to create a release"
done
[ -f "$CONTRACT" ] || fail "Missing production contract validator: $CONTRACT"
[ -n "${ONLYOFFICE_RELEASE_ROOT:-}" ] || fail 'ONLYOFFICE_RELEASE_ROOT is required'
 
RELEASE_ROOT=$(node -e '
const fs = require("node:fs");
const path = require("node:path");
let existing = path.resolve(process.argv[1]);
const missing = [];
while (!fs.existsSync(existing)) {
  missing.unshift(path.basename(existing));
  const parent = path.dirname(existing);
  if (parent === existing) process.exit(2);
  existing = parent;
}
process.stdout.write(path.join(fs.realpathSync(existing), ...missing));
' "$ONLYOFFICE_RELEASE_ROOT")
 
[ "$RELEASE_ROOT" != '/' ] || fail 'ONLYOFFICE_RELEASE_ROOT must not be the filesystem root'
[ "$RELEASE_ROOT" != "$PLUGIN_DIR" ] || fail 'ONLYOFFICE_RELEASE_ROOT must not be the plugin directory'
case "$RELEASE_ROOT" in
  "$DIST_DIR" | "$DIST_DIR"/*) fail 'ONLYOFFICE_RELEASE_ROOT must not be dist or a directory inside dist' ;;
esac
[ -d "$DIST_DIR" ] || fail "Missing fresh production build directory: $DIST_DIR"
 
node "$CONTRACT" validate-dist "$DIST_DIR"
mkdir -p "$RELEASE_ROOT"
TARGET=$(node "$CONTRACT" prepare-release-path "$RELEASE_ROOT")
TARGET_PARENT=${TARGET%/*}
STAGING=$(mktemp -d "$TARGET_PARENT/.eln-template-annotator.staging.XXXXXX")
 
node "$CONTRACT" copy-release "$DIST_DIR" "$STAGING"
node "$CONTRACT" validate-release "$STAGING"
 
if [ -e "$TARGET" ] || [ -L "$TARGET" ]; then
  [ ! -L "$TARGET" ] && [ -d "$TARGET" ] || fail "Immutable release target must be an ordinary directory: $TARGET"
  set +e
  diff -qr "$TARGET" "$STAGING" >/dev/null 2>&1
  diff_status=$?
  set -e
  case "$diff_status" in
    0)
      node "$CONTRACT" check-release "$TARGET"
      printf '%s\n' "$TARGET"
      exit 0
      ;;
    1) fail "Immutable release already exists with different content: $TARGET" ;;
    *) exit "$diff_status" ;;
  esac
fi
 
mv "$STAGING" "$TARGET"
STAGING=''
node "$CONTRACT" check-release "$TARGET"
printf '%s\n' "$TARGET"