@designcrowd/fe-shared-lib 1.8.4-edge-fallback-1 → 1.8.4-edge-fallback-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -123,7 +123,15 @@ npm link @designcrowd/fe-shared-lib # in consumer project
123
123
 
124
124
  ## Publishing (UAT)
125
125
 
126
- To test experimental versions without publishing to production:
127
- 1. Update `package.json` version to `[current]-[description]`
128
- 2. Run `docker build . --build-arg NPM_TOKEN=$NPM_TOKEN`
129
- 3. Update consumer package reference to the new version
126
+ Use `scripts/publish-uat.sh <suffix>` to publish a UAT build for testing in a consumer (e.g. BrandCrowd.Net). The script handles the version bump, bundle-translation, secret scanning of the tarball, and the commit. Examples:
127
+
128
+ ```bash
129
+ ./scripts/publish-uat.sh edge-fallback-0
130
+ ./scripts/publish-uat.sh edge-fallback-1 # next iteration
131
+ ```
132
+
133
+ It refuses to run on `master`/`main`, refuses if the version is already published, aborts on dangerous filenames or token-shaped strings inside the tarball, and only commits the bump after the registry confirms upload.
134
+
135
+ The npm publish token is read from `~/.config/designcrowd/npm-publish-token` (mode 600). Override with `NPM_PUBLISH_TOKEN_FILE` if it lives elsewhere. The token file is **not** stored anywhere in the repo.
136
+
137
+ The legacy `docker build . --build-arg NPM_TOKEN=...` flow still works but is brittle — prefer the script.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@designcrowd/fe-shared-lib",
3
- "version": "1.8.4-edge-fallback-1",
3
+ "version": "1.8.4-edge-fallback-2",
4
4
  "scripts": {
5
5
  "start": "run-p storybook watch:translation",
6
6
  "build": "npm run build:css --production",
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # publish-uat.sh — publish a UAT-suffixed version of @designcrowd/fe-shared-lib
4
+ #
5
+ # Usage: ./scripts/publish-uat.sh <suffix>
6
+ # Example: ./scripts/publish-uat.sh edge-fallback-2
7
+ #
8
+ # Reads the npm publish token from $NPM_PUBLISH_TOKEN_FILE
9
+ # (default ~/.config/designcrowd/npm-publish-token, mode 600).
10
+ # The token is never written into the repo.
11
+ #
12
+ # Workflow:
13
+ # 1. Validate branch (refuse master) and suffix.
14
+ # 2. Compute new version = <base>-<suffix>, refuse if already published.
15
+ # 3. Bump package.json, run bundle-translation.
16
+ # 4. npm pack — produces a tarball.
17
+ # 5. Secret scan: dangerous filenames + token-shaped strings + the
18
+ # literal token bytes from the token file (if it leaked into the
19
+ # tree somehow, this catches it).
20
+ # 6. npm publish <tarball> via a temp .npmrc in /tmp (mode 600,
21
+ # removed on exit).
22
+ # 7. git add + commit the version bump.
23
+ #
24
+ # Anything in steps 4-6 that fails leaves the working tree dirty so you
25
+ # can investigate. The commit only lands after the registry confirms
26
+ # the upload.
27
+
28
+ set -euo pipefail
29
+
30
+ PKG="@designcrowd/fe-shared-lib"
31
+ TOKEN_FILE="${NPM_PUBLISH_TOKEN_FILE:-$HOME/.config/designcrowd/npm-publish-token}"
32
+
33
+ abort() { echo "ABORT: $*" >&2; exit 1; }
34
+
35
+ # --- args ---
36
+ SUFFIX="${1:-}"
37
+ [[ -z "$SUFFIX" ]] && abort "usage: $0 <suffix> e.g. $0 edge-fallback-2"
38
+ [[ "$SUFFIX" =~ ^[A-Za-z0-9._-]+$ ]] || abort "suffix must be [A-Za-z0-9._-]+"
39
+
40
+ # --- repo state ---
41
+ cd "$(git rev-parse --show-toplevel)"
42
+ BRANCH=$(git symbolic-ref --short HEAD)
43
+ [[ "$BRANCH" == "master" || "$BRANCH" == "main" ]] && abort "refusing to publish from $BRANCH"
44
+
45
+ # --- token ---
46
+ [[ -f "$TOKEN_FILE" ]] || abort "no token at $TOKEN_FILE (set NPM_PUBLISH_TOKEN_FILE to override)"
47
+ TOKEN=$(tr -d '[:space:]' < "$TOKEN_FILE")
48
+ [[ -n "$TOKEN" ]] || abort "token file is empty: $TOKEN_FILE"
49
+
50
+ # --- compute version ---
51
+ BASE=$(node -p "require('./package.json').version.replace(/-.*/, '')")
52
+ NEW="$BASE-$SUFFIX"
53
+
54
+ if npm view "$PKG@$NEW" version >/dev/null 2>&1; then
55
+ abort "$PKG@$NEW already published — pick a new suffix"
56
+ fi
57
+
58
+ echo "==> publishing $PKG@$NEW from branch $BRANCH"
59
+
60
+ # --- bump + bundle ---
61
+ node -e "const fs=require('fs');const p=require('./package.json');p.version='$NEW';fs.writeFileSync('./package.json', JSON.stringify(p, null, 2)+'\n');"
62
+ echo "==> running bundle-translation"
63
+ npm run --silent bundle-translation >/dev/null
64
+
65
+ # --- pack ---
66
+ echo "==> packing"
67
+ TARBALL=$(npm pack --silent)
68
+ [[ -f "$TARBALL" ]] || abort "npm pack did not produce a tarball"
69
+
70
+ # Always clean up temp artifacts on exit
71
+ SCAN_DIR=$(mktemp -d)
72
+ TMP_NPMRC=$(mktemp /tmp/fe-shared-lib-publish.XXXXXX.npmrc)
73
+ chmod 600 "$TMP_NPMRC"
74
+ cleanup() { rm -rf "$SCAN_DIR"; rm -f "$TMP_NPMRC" "$TARBALL"; }
75
+ trap cleanup EXIT
76
+
77
+ # --- secret scan: filenames ---
78
+ echo "==> scanning $TARBALL"
79
+ DANGEROUS_PATHS='(^|/)(\.env(\..+)?|\.npmrc|\.npm-publish-token|id_rsa.*|id_ed25519.*|.*\.pem|.*\.key|.*token.*|.*secret.*|.*credential.*)$|(^|/)\.(aws|ssh|gnupg)/'
80
+ if BAD=$(tar tzf "$TARBALL" | grep -E -i "$DANGEROUS_PATHS" || true); [[ -n "$BAD" ]]; then
81
+ echo "$BAD" >&2
82
+ abort "dangerous filenames in tarball"
83
+ fi
84
+
85
+ # --- secret scan: contents ---
86
+ tar xzf "$TARBALL" -C "$SCAN_DIR"
87
+
88
+ # Token-shaped patterns. Tightened so the literal '${NPM_TOKEN}' template
89
+ # in the tracked npmrc file doesn't trip the check.
90
+ SECRET_PATTERNS='(npm_[A-Za-z0-9]{30,}|AKIA[0-9A-Z]{16}|ASIA[0-9A-Z]{16}|gh[pousr]_[A-Za-z0-9]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|sk_live_[A-Za-z0-9]{20,}|-----BEGIN [A-Z ]*PRIVATE KEY-----)'
91
+ if HITS=$(grep -REn -I -E "$SECRET_PATTERNS" "$SCAN_DIR" 2>/dev/null || true); [[ -n "$HITS" ]]; then
92
+ echo "$HITS" >&2
93
+ abort "secret-shaped string in tarball"
94
+ fi
95
+
96
+ # Belt-and-braces: the token's own bytes. If our publish token ever
97
+ # lands in a tracked file by accident, this catches it regardless of
98
+ # pattern-matching.
99
+ if grep -RFq "$TOKEN" "$SCAN_DIR" 2>/dev/null; then
100
+ abort "publish token bytes appear in tarball — DO NOT publish"
101
+ fi
102
+
103
+ FILES=$(tar tzf "$TARBALL" | wc -l | tr -d ' ')
104
+ SIZE=$(du -h "$TARBALL" | cut -f1)
105
+ echo "==> scan clean. $FILES files, $SIZE"
106
+
107
+ # --- publish ---
108
+ printf '//registry.npmjs.org/:_authToken=%s\n' "$TOKEN" > "$TMP_NPMRC"
109
+ echo "==> publishing"
110
+ npm publish "$TARBALL" --userconfig "$TMP_NPMRC"
111
+
112
+ # --- commit bump ---
113
+ git add -- package.json
114
+ git add -- src/bundles 2>/dev/null || true
115
+ git commit -m "bump version to $NEW" >/dev/null
116
+ echo
117
+ echo "Published $PKG@$NEW (commit $(git rev-parse --short HEAD))"
118
+ echo
119
+ echo "Install in BrandCrowd.Net:"
120
+ echo " npm i $PKG@$NEW"
Binary file
Binary file