@plasius/react-state 1.0.6 → 1.0.7

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.
@@ -6,6 +6,7 @@ on:
6
6
  permissions:
7
7
  contents: write
8
8
  id-token: write # for npm provenance (requires Node 18+ and npm >=9)
9
+ attestations: write
9
10
 
10
11
  jobs:
11
12
  publish:
@@ -24,9 +25,114 @@ jobs:
24
25
  - name: Install deps (CI)
25
26
  run: npm ci
26
27
 
28
+ - name: Update CHANGELOG.md (move Unreleased to new version)
29
+ env:
30
+ VERSION: ${{ steps.pkg.outputs.version }}
31
+ TAG: ${{ steps.pkg.outputs.tag }}
32
+ GITHUB_REPOSITORY: ${{ github.repository }}
33
+ verbose: true
34
+ run: |
35
+ set -euo pipefail
36
+ git config user.name "github-actions[bot]"
37
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
38
+
39
+ FILE="CHANGELOG.md"
40
+ if [ ! -f "$FILE" ]; then
41
+ echo "No CHANGELOG.md found; skipping changelog update."
42
+ exit 0
43
+ fi
44
+
45
+ DATE=$(date -u +%Y-%m-%d)
46
+ VERSION_LINE="## [${VERSION}] - ${DATE}"
47
+
48
+ # Identify Unreleased block boundaries
49
+ UNREL_START=$(grep -n '^## \[Unreleased\]' "$FILE" | cut -d: -f1 || true)
50
+ if [ -z "$UNREL_START" ]; then
51
+ echo "No '## [Unreleased]' section found; skipping changelog update."
52
+ exit 0
53
+ fi
54
+ NEXT_HDR=$(awk 'NR>'"$UNREL_START"' && /^## \[/{print NR; exit}' "$FILE")
55
+ if [ -z "$NEXT_HDR" ]; then
56
+ NEXT_HDR=$(wc -l < "$FILE")
57
+ NEXT_HDR=$((NEXT_HDR+1))
58
+ fi
59
+
60
+ # Extract sections
61
+ HEADER=$(sed -n "1,${UNREL_START}p" "$FILE")
62
+ UNREL_CONTENT=$(sed -n "$((UNREL_START+1)),$((NEXT_HDR-1))p" "$FILE")
63
+ TAIL=$(sed -n "${NEXT_HDR},\$p" "$FILE")
64
+
65
+ # Prepare new Unreleased template (Keep a Changelog style) without tabs/indent issues
66
+ NEW_UNRELEASED=$(printf '%s\n' \
67
+ '' \
68
+ '- **Added**' \
69
+ ' - (placeholder)' \
70
+ '' \
71
+ '- **Changed**' \
72
+ ' - (placeholder)' \
73
+ '' \
74
+ '- **Fixed**' \
75
+ ' - (placeholder)' \
76
+ '' \
77
+ '- **Security**' \
78
+ ' - (placeholder)')
79
+
80
+ # Build the new CHANGELOG content
81
+ TMP_FILE=$(mktemp)
82
+ {
83
+ printf "%s\n" "$HEADER"
84
+ printf "%s\n\n" "$NEW_UNRELEASED"
85
+ printf "%s\n" "$VERSION_LINE"
86
+ # If Unreleased was empty, at least add a placeholder so the section isn't blank
87
+ if [ -z "$(echo "$UNREL_CONTENT" | tr -d '\n' | tr -d '[:space:]')" ]; then
88
+ printf "### Changed\n- (no notable changes)\n\n"
89
+ else
90
+ printf "%s\n" "$UNREL_CONTENT"
91
+ # Ensure a trailing newline after the inserted section
92
+ printf "\n"
93
+ fi
94
+ printf "%s\n" "$TAIL"
95
+ } > "$TMP_FILE"
96
+
97
+ mv "$TMP_FILE" "$FILE"
98
+
99
+ # Update bottom compare links
100
+ # Update [Unreleased] compare to start at v${VERSION}
101
+ COMPARE_URL="https://github.com/${GITHUB_REPOSITORY}/compare/v${VERSION}...HEAD"
102
+ awk -v repl="[Unreleased]: ${COMPARE_URL}" 'BEGIN{OFS=FS} { if ($0 ~ /^\[Unreleased\]: /) { print repl } else { print } }' "$FILE" > "$FILE.tmp"
103
+ mv "$FILE.tmp" "$FILE"
104
+
105
+ # Append a link for the new version if not present
106
+ if ! grep -q "^\[${VERSION}\]:" "$FILE"; then
107
+ echo "[${VERSION}]: https://github.com/${GITHUB_REPOSITORY}/releases/tag/v${VERSION}" >> "$FILE"
108
+ fi
109
+
110
+ git add "$FILE"
111
+ git commit -m "docs(changelog): release v${VERSION}"
112
+ git push
113
+
114
+ - name: Test (coverage)
115
+ run: npm run test -- --coverage
116
+
117
+ - name: Upload coverage to Codecov
118
+ uses: codecov/codecov-action@v4
119
+ with:
120
+ token: ${{ secrets.CODECOV_TOKEN }}
121
+ files: ./coverage/lcov.info
122
+ flags: unittests
123
+ fail_ci_if_error: true
124
+
27
125
  - name: Build
28
126
  run: npm run build --if-present
29
127
 
128
+ - name: Generate SBOM (CycloneDX)
129
+ run: npm sbom --sbom-format=cyclonedx --sbom-type=library --omit dev > sbom.cdx.json
130
+
131
+ - name: Attest SBOM (GitHub Artifact Attestations)
132
+ uses: actions/attest-build-provenance@v3
133
+ with:
134
+ subject-path: sbom.cdx.json
135
+
30
136
  - name: Bump version & decide publish flags
31
137
  id: pkg
32
138
  env:
@@ -38,6 +144,8 @@ jobs:
38
144
  NEW_VER=$(npm version patch -m "chore: release v%s [skip ci]")
39
145
  echo "New version: $NEW_VER"
40
146
  git push --follow-tags
147
+
148
+ # Expose tag (vX.Y.Z) and version (X.Y.Z) for later steps
41
149
  VER_NO_V=${NEW_VER#v}
42
150
  echo "tag=$NEW_VER" >> "$GITHUB_OUTPUT"
43
151
  echo "version=$VER_NO_V" >> "$GITHUB_OUTPUT"
@@ -57,13 +165,19 @@ jobs:
57
165
  set -euo pipefail
58
166
  TAG="${{ steps.pkg.outputs.tag }}"
59
167
  if gh release view "$TAG" >/dev/null 2>&1; then
60
- echo "Release $TAG already exists; skipping creation."
168
+ echo "Release $TAG already exists; uploading SBOM asset."
61
169
  else
62
170
  gh release create "$TAG" \
63
171
  --title "Release $TAG" \
64
172
  --generate-notes \
65
173
  --latest
66
174
  fi
175
+ # Upload/overwrite the SBOM asset on the release
176
+ if [ -f sbom.cdx.json ]; then
177
+ gh release upload "$TAG" sbom.cdx.json --clobber
178
+ else
179
+ echo "No SBOM generated; skipping upload."
180
+ fi
67
181
 
68
182
  - name: Publish
69
183
  env:
package/CHANGELOG.md CHANGED
@@ -9,6 +9,20 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ - **Added**
13
+ - (placeholder)
14
+
15
+ - **Changed**
16
+ - (placeholder)
17
+
18
+ - **Fixed**
19
+ - (placeholder)
20
+
21
+ - **Security**
22
+ - (placeholder)
23
+
24
+ ## [] - 2025-09-17
25
+
12
26
  - **Added**
13
27
  - (placeholder) Add new hooks, scoped store features, or context helpers here.
14
28
 
@@ -56,5 +70,6 @@ The format is based on **[Keep a Changelog](https://keepachangelog.com/en/1.1.0/
56
70
 
57
71
  ---
58
72
 
59
- [Unreleased]: https://github.com/Plasius-LTD/react-state/compare/v1.0.0...HEAD
73
+ [Unreleased]: https://github.com/Plasius-LTD/react-state/compare/v...HEAD
60
74
  [1.0.0]: https://github.com/Plasius-LTD/react-state/releases/tag/v1.0.0
75
+ []: https://github.com/Plasius-LTD/react-state/releases/tag/v
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plasius/react-state",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Tiny, testable, typesafe React Scoped Store helper.",
5
5
  "keywords": [
6
6
  "react",
@@ -54,6 +54,7 @@
54
54
  "@types/node": "^24.3.1",
55
55
  "@typescript-eslint/eslint-plugin": "^8.43.0",
56
56
  "@typescript-eslint/parser": "^8.43.0",
57
+ "@vitest/coverage-v8": "^3.2.4",
57
58
  "eslint": "^9.35.0",
58
59
  "jsdom": "^27.0.0",
59
60
  "tsup": "^8.5.0",
package/sbom.cdx.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
+ "bomFormat": "CycloneDX",
4
+ "specVersion": "1.5",
5
+ "serialNumber": "urn:uuid:070834d4-7af4-4992-bf40-fcf52c4bf035",
6
+ "version": 1,
7
+ "metadata": {
8
+ "timestamp": "2025-09-17T15:31:48.552Z",
9
+ "lifecycles": [
10
+ {
11
+ "phase": "build"
12
+ }
13
+ ],
14
+ "tools": [
15
+ {
16
+ "vendor": "npm",
17
+ "name": "cli",
18
+ "version": "10.9.3"
19
+ }
20
+ ],
21
+ "component": {
22
+ "bom-ref": "@plasius/react-state@1.0.6",
23
+ "type": "library",
24
+ "name": "react-state",
25
+ "version": "1.0.6",
26
+ "scope": "required",
27
+ "author": "Plasius LTD",
28
+ "description": "Tiny, testable, typesafe React Scoped Store helper.",
29
+ "purl": "pkg:npm/%40plasius/react-state@1.0.6",
30
+ "properties": [
31
+ {
32
+ "name": "cdx:npm:package:path",
33
+ "value": ""
34
+ }
35
+ ],
36
+ "externalReferences": [
37
+ {
38
+ "type": "vcs",
39
+ "url": "git+https://github.com/Plasius-LTD/react-state.git"
40
+ },
41
+ {
42
+ "type": "website",
43
+ "url": "https://github.com/Plasius-LTD/react-state#readme"
44
+ },
45
+ {
46
+ "type": "issue-tracker",
47
+ "url": "https://github.com/Plasius-LTD/react-state/issues"
48
+ }
49
+ ],
50
+ "licenses": [
51
+ {
52
+ "license": {
53
+ "id": "Apache-2.0"
54
+ }
55
+ }
56
+ ]
57
+ }
58
+ },
59
+ "components": [],
60
+ "dependencies": [
61
+ {
62
+ "ref": "@plasius/react-state@1.0.6",
63
+ "dependsOn": []
64
+ }
65
+ ]
66
+ }
package/vitest.config.js CHANGED
@@ -6,8 +6,15 @@ export default defineConfig({
6
6
  globals: true,
7
7
  include: ["tests/**/*.test.{ts,tsx}"],
8
8
  coverage: {
9
+ provider: "v8",
9
10
  reporter: ["text", "lcov"],
10
- exclude: ["tests/**", "dist/**"],
11
+ reportsDirectory: "./coverage",
12
+ exclude: [
13
+ "tests/**",
14
+ "dist/**",
15
+ "**/*.config.{js,ts}",
16
+ "**/.eslintrc.{js,cjs}",
17
+ ],
11
18
  },
12
19
  },
13
20
  });