刘光辉
7 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/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"
CANONICAL_STAGING=''
COMPATIBILITY_STAGING=''
TARGET_PARENT=''
 
cleanup() {
  status=$?
  trap - EXIT HUP INT TERM
  for staging in "$CANONICAL_STAGING" "$COMPATIBILITY_STAGING"; do
    [ -n "$staging" ] || continue
    if [ -n "$TARGET_PARENT" ]; then
      case "$staging" in
      "$TARGET_PARENT"/.eln-record-filler.staging.* | "$TARGET_PARENT"/.eln-template-filler.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
  done
  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"
CANONICAL_TARGET=$(node "$CONTRACT" prepare-release-path "$RELEASE_ROOT" eln-record-filler)
COMPATIBILITY_TARGET=$(node "$CONTRACT" prepare-release-path "$RELEASE_ROOT" eln-template-filler)
TARGET_PARENT=${CANONICAL_TARGET%/*}
[ "${COMPATIBILITY_TARGET%/*}" = "$TARGET_PARENT" ] || fail 'Release targets must share one parent'
 
CANONICAL_STAGING=$(mktemp -d "$TARGET_PARENT/.eln-record-filler.staging.XXXXXX")
COMPATIBILITY_STAGING=$(mktemp -d "$TARGET_PARENT/.eln-template-filler.staging.XXXXXX")
node "$CONTRACT" copy-release "$DIST_DIR" "$CANONICAL_STAGING"
node "$CONTRACT" validate-release "$CANONICAL_STAGING"
node "$CONTRACT" copy-release "$DIST_DIR" "$COMPATIBILITY_STAGING"
node "$CONTRACT" validate-release "$COMPATIBILITY_STAGING"
 
check_existing_target() {
  target=$1
  staging=$2
  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" ;;
      1) fail "Immutable release already exists with different content: $target" ;;
      *) exit "$diff_status" ;;
    esac
  fi
}
 
check_existing_target "$CANONICAL_TARGET" "$CANONICAL_STAGING"
check_existing_target "$COMPATIBILITY_TARGET" "$COMPATIBILITY_STAGING"
 
if [ ! -e "$CANONICAL_TARGET" ]; then
  mv "$CANONICAL_STAGING" "$CANONICAL_TARGET"
  CANONICAL_STAGING=''
fi
if [ ! -e "$COMPATIBILITY_TARGET" ]; then
  mv "$COMPATIBILITY_STAGING" "$COMPATIBILITY_TARGET"
  COMPATIBILITY_STAGING=''
fi
node "$CONTRACT" check-release "$CANONICAL_TARGET"
node "$CONTRACT" check-release "$COMPATIBILITY_TARGET"
printf '%s\n' "$CANONICAL_TARGET"