Compare commits
6
Commits
feat/build
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d25beede91 | ||
|
|
16b690c8c0 | ||
|
|
2036a0261e | ||
|
|
66c8f6b94b | ||
|
|
1bf21404bd | ||
|
|
9ec0f1c74a |
No files matched your search
@@ -9,6 +9,9 @@ on:
|
||||
ref:
|
||||
required: true
|
||||
type: string
|
||||
commit:
|
||||
required: true
|
||||
type: string
|
||||
dry_run:
|
||||
required: true
|
||||
type: boolean
|
||||
@@ -36,6 +39,20 @@ jobs:
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Verify release source
|
||||
env:
|
||||
RELEASE_COMMIT: ${{ inputs.commit }}
|
||||
run: |
|
||||
if [[ ! "$RELEASE_COMMIT" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "Invalid release commit: $RELEASE_COMMIT"
|
||||
exit 1
|
||||
fi
|
||||
checkout_commit="$(git rev-parse HEAD)"
|
||||
if [[ "$checkout_commit" != "$RELEASE_COMMIT" ]]; then
|
||||
echo "Checked out $checkout_commit, expected $RELEASE_COMMIT."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
|
||||
with:
|
||||
@@ -85,6 +102,20 @@ jobs:
|
||||
ref: ${{ inputs.ref }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Verify release source
|
||||
env:
|
||||
RELEASE_COMMIT: ${{ inputs.commit }}
|
||||
run: |
|
||||
if [[ ! "$RELEASE_COMMIT" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "Invalid release commit: $RELEASE_COMMIT"
|
||||
exit 1
|
||||
fi
|
||||
checkout_commit="$(git rev-parse HEAD)"
|
||||
if [[ "$checkout_commit" != "$RELEASE_COMMIT" ]]; then
|
||||
echo "Checked out $checkout_commit, expected $RELEASE_COMMIT."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Download UI assets
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
@@ -119,7 +150,7 @@ jobs:
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
build-args: |
|
||||
APP_VERSION=${{ inputs.version }}
|
||||
APP_COMMIT_HASH=${{ github.sha }}
|
||||
APP_COMMIT_HASH=${{ inputs.commit }}
|
||||
SKIP_UI_BUILD=true
|
||||
outputs: type=docker
|
||||
cache-from: type=gha,scope=release-${{ matrix.platform_pair }}
|
||||
@@ -134,10 +165,9 @@ jobs:
|
||||
file: ./Dockerfile
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
build-args: |
|
||||
APP_VERSION=${{ inputs.version }}
|
||||
APP_COMMIT_HASH=${{ github.sha }}
|
||||
APP_COMMIT_HASH=${{ inputs.commit }}
|
||||
SKIP_UI_BUILD=true
|
||||
outputs: type=image,push=true,name=${{ env.DOCKER_IMG }},push-by-digest=true,name-canonical=true
|
||||
cache-from: type=gha,scope=release-${{ matrix.platform_pair }}
|
||||
@@ -197,6 +227,16 @@ jobs:
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
||||
|
||||
- name: Prepare release metadata
|
||||
env:
|
||||
RELEASE_COMMIT: ${{ inputs.commit }}
|
||||
run: |
|
||||
if [[ ! "$RELEASE_COMMIT" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "Invalid release commit: $RELEASE_COMMIT"
|
||||
exit 1
|
||||
fi
|
||||
echo "RELEASE_COMMIT_SHORT=${RELEASE_COMMIT:0:7}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Generate Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
|
||||
@@ -205,7 +245,7 @@ jobs:
|
||||
tags: |
|
||||
type=semver,pattern={{version}},value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.version }}
|
||||
type=sha
|
||||
type=raw,value=sha-${{ env.RELEASE_COMMIT_SHORT }}
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 # v4.4.0
|
||||
|
||||
@@ -13,6 +13,11 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
release_commit:
|
||||
description: "Immutable commit to tag when the release tag does not exist"
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
outputs:
|
||||
version:
|
||||
description: "Version"
|
||||
@@ -20,6 +25,9 @@ on:
|
||||
ref:
|
||||
description: "Git ref to build"
|
||||
value: ${{ jobs.tagging.outputs.ref }}
|
||||
commit:
|
||||
description: "Release source commit"
|
||||
value: ${{ jobs.tagging.outputs.commit }}
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -52,28 +60,31 @@ jobs:
|
||||
echo "Version: $VERSION"
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Create Tag
|
||||
if: ${{ !inputs.dry_run }}
|
||||
- name: Resolve release target
|
||||
id: target
|
||||
env:
|
||||
DEFAULT_COMMIT: ${{ github.sha }}
|
||||
DRY_RUN: ${{ inputs.dry_run }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
REQUESTED_COMMIT: ${{ inputs.release_commit }}
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
run: |
|
||||
resolve_tag_commit() {
|
||||
local object_type="$1"
|
||||
local object_sha="$2"
|
||||
local depth=0
|
||||
|
||||
if [[ "$object_type" == "tag" ]]; then
|
||||
while [[ "$object_type" == "tag" ]]; do
|
||||
depth=$((depth + 1))
|
||||
if (( depth > 8 )); then
|
||||
echo "Tag $VERSION has too many nested tag objects." >&2
|
||||
return 1
|
||||
fi
|
||||
IFS=$'\t' read -r object_type object_sha < <(
|
||||
gh api "repos/$GITHUB_REPOSITORY/git/tags/$object_sha" \
|
||||
--jq '.object | [.type, .sha] | @tsv'
|
||||
)
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$object_type" != "commit" ]]; then
|
||||
echo "Tag $VERSION resolves to unsupported object type $object_type." >&2
|
||||
@@ -83,31 +94,163 @@ jobs:
|
||||
printf '%s\n' "$object_sha"
|
||||
}
|
||||
|
||||
release_sha="$(git rev-parse HEAD)"
|
||||
requested_commit="$(tr '[:upper:]' '[:lower:]' <<< "$REQUESTED_COMMIT")"
|
||||
if [[ -n "$requested_commit" && ! "$requested_commit" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "release_commit must be a full 40-character commit SHA."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tag_ref="$(
|
||||
gh api "repos/$GITHUB_REPOSITORY/git/matching-refs/tags/$VERSION" \
|
||||
--jq ".[] | select(.ref == \"refs/tags/$VERSION\") | [.object.type, .object.sha] | @tsv"
|
||||
)"
|
||||
|
||||
if [[ -z "$tag_ref" ]]; then
|
||||
gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \
|
||||
-f ref="refs/tags/$VERSION" \
|
||||
-f sha="$release_sha" > /dev/null
|
||||
tag_ref="$(
|
||||
gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$VERSION" \
|
||||
--jq '.object | [.type, .sha] | @tsv'
|
||||
)"
|
||||
echo "Created tag $VERSION at $release_sha."
|
||||
fi
|
||||
|
||||
IFS=$'\t' read -r tag_type tag_sha <<< "$tag_ref"
|
||||
tag_commit="$(resolve_tag_commit "$tag_type" "$tag_sha")"
|
||||
if [[ "$tag_commit" != "$release_sha" ]]; then
|
||||
echo "Tag $VERSION points to $tag_commit, expected $release_sha."
|
||||
tag_exists=false
|
||||
if [[ -n "$tag_ref" ]]; then
|
||||
IFS=$'\t' read -r tag_type tag_sha <<< "$tag_ref"
|
||||
release_commit="$(resolve_tag_commit "$tag_type" "$tag_sha")"
|
||||
tag_exists=true
|
||||
if [[ -n "$requested_commit" && "$release_commit" != "$requested_commit" ]]; then
|
||||
echo "Tag $VERSION points to $release_commit, not requested commit $requested_commit."
|
||||
exit 1
|
||||
fi
|
||||
elif [[ -n "$requested_commit" ]]; then
|
||||
release_commit="$requested_commit"
|
||||
elif [[ "$DRY_RUN" == "true" ]]; then
|
||||
release_commit="$DEFAULT_COMMIT"
|
||||
else
|
||||
echo "Tag $VERSION does not exist and release_commit was not provided."
|
||||
echo "Use the reviewed release pull request merge commit for a production retry."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Verified tag $VERSION at $release_sha."
|
||||
verified_commit="$(
|
||||
gh api "repos/$GITHUB_REPOSITORY/git/commits/$release_commit" --jq '.sha'
|
||||
)"
|
||||
if [[ "$verified_commit" != "$release_commit" ]]; then
|
||||
echo "Unable to verify release commit $release_commit."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "commit=$release_commit" >> "$GITHUB_OUTPUT"
|
||||
echo "tag_exists=$tag_exists" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ steps.target.outputs.commit }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate release source
|
||||
env:
|
||||
RELEASE_COMMIT: ${{ steps.target.outputs.commit }}
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
run: |
|
||||
checkout_commit="$(git rev-parse HEAD)"
|
||||
if [[ "$checkout_commit" != "$RELEASE_COMMIT" ]]; then
|
||||
echo "Checked out $checkout_commit, expected $RELEASE_COMMIT."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git fetch --no-tags origin \
|
||||
"+refs/heads/master:refs/remotes/origin/master"
|
||||
if ! git merge-base --is-ancestor "$RELEASE_COMMIT" origin/master; then
|
||||
echo "Release commit $RELEASE_COMMIT is not reachable from master."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
package_version="${VERSION#v}"
|
||||
app_version="$(
|
||||
sed -n 's/^var Version = "\(v[0-9][0-9.]*\)"$/\1/p' internal/config/version.go
|
||||
)"
|
||||
ui_version="$(jq -r '.version' ui/artalk/package.json)"
|
||||
docs_version="$(jq -r '.latest' docs/docs/code/ArtalkVersion.json)"
|
||||
if [[ "$app_version" != "$VERSION" ||
|
||||
"$ui_version" != "$package_version" ||
|
||||
"$docs_version" != "$package_version" ]]; then
|
||||
echo "Release commit versions do not match $VERSION: app=$app_version ui=$ui_version docs=$docs_version."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create Tag
|
||||
if: ${{ !inputs.dry_run }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
RELEASE_COMMIT: ${{ steps.target.outputs.commit }}
|
||||
TAG_EXISTS: ${{ steps.target.outputs.tag_exists }}
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
run: |
|
||||
resolve_tag_commit() {
|
||||
local object_type="$1"
|
||||
local object_sha="$2"
|
||||
local depth=0
|
||||
|
||||
while [[ "$object_type" == "tag" ]]; do
|
||||
depth=$((depth + 1))
|
||||
if (( depth > 8 )); then
|
||||
echo "Tag $VERSION has too many nested tag objects." >&2
|
||||
return 1
|
||||
fi
|
||||
IFS=$'\t' read -r object_type object_sha < <(
|
||||
gh api "repos/$GITHUB_REPOSITORY/git/tags/$object_sha" \
|
||||
--jq '.object | [.type, .sha] | @tsv'
|
||||
)
|
||||
done
|
||||
|
||||
if [[ "$object_type" != "commit" ]]; then
|
||||
echo "Tag $VERSION resolves to unsupported object type $object_type." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
printf '%s\n' "$object_sha"
|
||||
}
|
||||
|
||||
get_tag_ref() {
|
||||
gh api "repos/$GITHUB_REPOSITORY/git/matching-refs/tags/$VERSION" \
|
||||
--jq ".[] | select(.ref == \"refs/tags/$VERSION\") | [.object.type, .object.sha] | @tsv"
|
||||
}
|
||||
|
||||
if [[ "$TAG_EXISTS" != "true" ]]; then
|
||||
tag_object_sha="$(
|
||||
gh api --method POST "repos/$GITHUB_REPOSITORY/git/tags" \
|
||||
-f tag="$VERSION" \
|
||||
-f message="Release $VERSION" \
|
||||
-f object="$RELEASE_COMMIT" \
|
||||
-f type=commit \
|
||||
--jq '.sha'
|
||||
)"
|
||||
|
||||
if ! create_error="$(
|
||||
gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \
|
||||
-f ref="refs/tags/$VERSION" \
|
||||
-f sha="$tag_object_sha" 2>&1
|
||||
)"; then
|
||||
tag_ref="$(get_tag_ref)"
|
||||
if [[ -z "$tag_ref" ]]; then
|
||||
printf '%s\n' "$create_error" >&2
|
||||
echo "GitHub rejected tag $VERSION. Check the active tag rulesets; tag targets must not require linear history." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Tag $VERSION was created concurrently; verifying it."
|
||||
else
|
||||
echo "Created annotated tag $VERSION at $RELEASE_COMMIT."
|
||||
fi
|
||||
fi
|
||||
|
||||
tag_ref="$(get_tag_ref)"
|
||||
if [[ -z "$tag_ref" ]]; then
|
||||
echo "Tag $VERSION is missing after creation."
|
||||
exit 1
|
||||
fi
|
||||
IFS=$'\t' read -r tag_type tag_sha <<< "$tag_ref"
|
||||
tag_commit="$(resolve_tag_commit "$tag_type" "$tag_sha")"
|
||||
if [[ "$tag_commit" != "$RELEASE_COMMIT" ]]; then
|
||||
echo "Tag $VERSION points to $tag_commit, expected $RELEASE_COMMIT."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Verified tag $VERSION at $RELEASE_COMMIT."
|
||||
|
||||
- name: Comment tag info to PR
|
||||
uses: ./.github/actions/comment
|
||||
@@ -118,4 +261,5 @@ jobs:
|
||||
🔖 Tagged version [${{ steps.version.outputs.version }}](https://github.com/ArtalkJS/Artalk/tree/${{ steps.version.outputs.version }}) and updated the [CHANGELOG.md](https://github.com/ArtalkJS/Artalk/blob/master/CHANGELOG.md).
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
ref: ${{ inputs.dry_run && github.sha || steps.version.outputs.version }}
|
||||
ref: ${{ inputs.dry_run && steps.target.outputs.commit || steps.version.outputs.version }}
|
||||
commit: ${{ steps.target.outputs.commit }}
|
||||
@@ -12,9 +12,6 @@ on:
|
||||
dry_run:
|
||||
required: true
|
||||
type: boolean
|
||||
secrets:
|
||||
NPM_TOKEN:
|
||||
required: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -39,8 +36,7 @@ jobs:
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version: 22.x
|
||||
registry-url: https://registry.npmjs.org/
|
||||
node-version: 24.x
|
||||
package-manager-cache: false
|
||||
|
||||
- name: Install dependencies
|
||||
@@ -49,15 +45,32 @@ jobs:
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
|
||||
- name: Pack npm package
|
||||
env:
|
||||
VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
package_version="v$(node --print "require('./ui/artalk/package.json').version")"
|
||||
if [[ "$package_version" != "$VERSION" ]]; then
|
||||
echo "Package version $package_version does not match release version $VERSION."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
pnpm --filter artalk pack --pack-destination "$RUNNER_TEMP"
|
||||
package_file="$RUNNER_TEMP/artalk-${package_version#v}.tgz"
|
||||
if [[ ! -f "$package_file" ]]; then
|
||||
echo "Expected package tarball was not created: $package_file"
|
||||
exit 1
|
||||
fi
|
||||
echo "PACKAGE_FILE=$package_file" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Validate package
|
||||
if: ${{ inputs.dry_run }}
|
||||
run: pnpm publish -F artalk --no-git-checks --dry-run
|
||||
run: npm publish "$PACKAGE_FILE" --dry-run --access public
|
||||
|
||||
- name: Publish
|
||||
if: ${{ !inputs.dry_run }}
|
||||
run: pnpm publish -F artalk --no-git-checks --provenance --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
# npm validates build.yml, the calling workflow, for trusted publishing.
|
||||
run: npm publish "$PACKAGE_FILE" --access public
|
||||
|
||||
# GitHub Packages
|
||||
#
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Build and Publish
|
||||
run-name: Build and Publish (${{ github.head_ref || github.ref }}) ${{ inputs.dry_run && '(🧪 Dry-Run)' || '' }}
|
||||
run-name: Build and Publish (${{ inputs.version || github.head_ref || github.ref }}) ${{ inputs.dry_run && '(🧪 Dry-Run)' || '' }}
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -15,6 +15,10 @@ on:
|
||||
version:
|
||||
description: "Release version (for example, v2.10.0)"
|
||||
type: string
|
||||
required: true
|
||||
release_commit:
|
||||
description: "Full release commit SHA (required when a production retry has no tag)"
|
||||
type: string
|
||||
required: false
|
||||
build_items:
|
||||
description: "Build items"
|
||||
@@ -57,6 +61,7 @@ jobs:
|
||||
issue_number: ${{ github.event.pull_request.number || 0 }}
|
||||
dry_run: ${{ inputs.dry_run || false }}
|
||||
version: ${{ inputs.version || '' }}
|
||||
release_commit: ${{ github.event.pull_request.merge_commit_sha || inputs.release_commit || '' }}
|
||||
|
||||
# Build the UI
|
||||
ui:
|
||||
@@ -70,8 +75,6 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
secrets:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
# Build the Docker image
|
||||
docker:
|
||||
@@ -81,6 +84,7 @@ jobs:
|
||||
with:
|
||||
version: ${{ needs.tagging.outputs.version }}
|
||||
ref: ${{ needs.tagging.outputs.ref }}
|
||||
commit: ${{ needs.tagging.outputs.commit }}
|
||||
dry_run: ${{ inputs.dry_run || false }}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -45,6 +45,7 @@ jobs:
|
||||
- name: Handle Version Number
|
||||
env:
|
||||
CUSTOM_VERSION: ${{ inputs.custom_version }}
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
SEMVER_INCREMENT: ${{ inputs.semver }}
|
||||
run: |
|
||||
PREV_VERSION="$(git describe --tags --abbrev=0 --match 'v*')"
|
||||
@@ -53,6 +54,31 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! git merge-base --is-ancestor "$PREV_VERSION" HEAD; then
|
||||
echo "Latest release tag $PREV_VERSION is not an ancestor of master."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CURRENT_APP_VERSION="$(
|
||||
sed -n 's/^var Version = "\(v[0-9][0-9.]*\)"$/\1/p' internal/config/version.go
|
||||
)"
|
||||
CURRENT_UI_VERSION="$(jq -r '.version' ui/artalk/package.json)"
|
||||
CURRENT_DOCS_VERSION="$(jq -r '.latest' docs/docs/code/ArtalkVersion.json)"
|
||||
CURRENT_PACKAGE_VERSION="${CURRENT_APP_VERSION#v}"
|
||||
|
||||
if [[ -z "$CURRENT_APP_VERSION" ||
|
||||
"$CURRENT_UI_VERSION" != "$CURRENT_PACKAGE_VERSION" ||
|
||||
"$CURRENT_DOCS_VERSION" != "$CURRENT_PACKAGE_VERSION" ]]; then
|
||||
echo "Release versions are inconsistent: app=$CURRENT_APP_VERSION ui=$CURRENT_UI_VERSION docs=$CURRENT_DOCS_VERSION."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$CURRENT_APP_VERSION" != "$PREV_VERSION" ]]; then
|
||||
echo "Source version $CURRENT_APP_VERSION does not match the latest release tag $PREV_VERSION."
|
||||
echo "If the release PR was already merged, recover it with Build and Publish instead of preparing the release again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$CUSTOM_VERSION" ]]; then
|
||||
NEXT_VERSION="$CUSTOM_VERSION"
|
||||
else
|
||||
@@ -72,6 +98,52 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
version_is_greater() {
|
||||
local next_version="${1#v}"
|
||||
local previous_version="${2#v}"
|
||||
local -a next_parts previous_parts
|
||||
local index next_part previous_part
|
||||
|
||||
IFS='.' read -r -a next_parts <<< "$next_version"
|
||||
IFS='.' read -r -a previous_parts <<< "$previous_version"
|
||||
for index in 0 1 2; do
|
||||
next_part=$((10#${next_parts[$index]}))
|
||||
previous_part=$((10#${previous_parts[$index]}))
|
||||
if (( next_part > previous_part )); then
|
||||
return 0
|
||||
fi
|
||||
if (( next_part < previous_part )); then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
if ! version_is_greater "$NEXT_VERSION" "$PREV_VERSION"; then
|
||||
echo "Release version $NEXT_VERSION must be greater than $PREV_VERSION."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if git show-ref --verify --quiet "refs/tags/$NEXT_VERSION"; then
|
||||
echo "Release tag $NEXT_VERSION already exists."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
release_branch="release/$NEXT_VERSION"
|
||||
existing_pr="$(
|
||||
gh pr list \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--head "$release_branch" \
|
||||
--base master \
|
||||
--state open \
|
||||
--json number,url \
|
||||
--jq 'if length == 0 then "" else "#\(.[0].number) \(.[0].url)" end'
|
||||
)"
|
||||
if [[ -n "$existing_pr" ]]; then
|
||||
echo "Release pull request $existing_pr already exists for $NEXT_VERSION."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PREV_VERSION=${PREV_VERSION}" >> "$GITHUB_ENV"
|
||||
echo "VERSION=${NEXT_VERSION}" >> "$GITHUB_ENV"
|
||||
|
||||
@@ -110,6 +182,53 @@ jobs:
|
||||
PACKAGE_VERSION="$PACKAGE_VERSION" perl -pi -e \
|
||||
's#"latest"(\W+)?:(\W+)?".*?"#"latest": "$ENV{PACKAGE_VERSION}"#g' docs/docs/code/ArtalkVersion.json
|
||||
|
||||
- name: Validate Release Changes
|
||||
run: |
|
||||
PACKAGE_VERSION="${VERSION#v}"
|
||||
APP_VERSION="$(
|
||||
sed -n 's/^var Version = "\(v[0-9][0-9.]*\)"$/\1/p' internal/config/version.go
|
||||
)"
|
||||
UI_VERSION="$(jq -r '.version' ui/artalk/package.json)"
|
||||
DOCS_VERSION="$(jq -r '.latest' docs/docs/code/ArtalkVersion.json)"
|
||||
|
||||
if [[ "$APP_VERSION" != "$VERSION" ||
|
||||
"$UI_VERSION" != "$PACKAGE_VERSION" ||
|
||||
"$DOCS_VERSION" != "$PACKAGE_VERSION" ]]; then
|
||||
echo "Generated release versions are inconsistent: app=$APP_VERSION ui=$UI_VERSION docs=$DOCS_VERSION."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
changelog_entries="$(grep -cF "## [$VERSION]" CHANGELOG.md || true)"
|
||||
if [[ "$changelog_entries" != "1" ]]; then
|
||||
echo "Expected one CHANGELOG entry for $VERSION, found $changelog_entries."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
first_changelog_version="$(
|
||||
sed -n 's/^## \[\(v[0-9][^]]*\)\].*/\1/p' CHANGELOG.md | head -n 1
|
||||
)"
|
||||
if [[ "$first_changelog_version" != "$VERSION" ]]; then
|
||||
echo "The first CHANGELOG release is $first_changelog_version, expected $VERSION."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
expected_changes="$(
|
||||
printf '%s\n' \
|
||||
CHANGELOG.md \
|
||||
docs/docs/code/ArtalkVersion.json \
|
||||
internal/config/version.go \
|
||||
ui/artalk/package.json |
|
||||
sort
|
||||
)"
|
||||
actual_changes="$(git diff --name-only | sort)"
|
||||
if [[ "$actual_changes" != "$expected_changes" ]]; then
|
||||
echo "Unexpected release file set:"
|
||||
git diff --name-only
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git diff --check
|
||||
|
||||
- name: Print Git Diff
|
||||
run: git diff
|
||||
|
||||
|
||||
@@ -70,6 +70,14 @@ jobs:
|
||||
if: ${{ matrix.quality }}
|
||||
run: pnpm build:plugins
|
||||
|
||||
- name: Plugins Type Test
|
||||
if: ${{ matrix.quality }}
|
||||
run: pnpm test:plugins
|
||||
|
||||
- name: Plugins Package Test
|
||||
if: ${{ matrix.quality }}
|
||||
run: pnpm test:plugins:attw
|
||||
|
||||
- name: Lint
|
||||
if: ${{ matrix.quality }}
|
||||
run: pnpm eslint ui && pnpm prettier --check ui
|
||||
|
||||
@@ -40,6 +40,8 @@ export default defineConfig(
|
||||
'**/*.config.js',
|
||||
'**/*.config.ts',
|
||||
'**/*.d.ts',
|
||||
'**/*.d.cts',
|
||||
'**/*.d.mts',
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
"build:auth": "pnpm -F @artalk/plugin-auth build",
|
||||
"build:plugin-kit": "pnpm -F @artalk/plugin-kit build",
|
||||
"build:eslint-plugin": "pnpm -F eslint-plugin-artalk build",
|
||||
"test:plugins": "pnpm -F @artalk/plugin-* exec tsc --noEmit && pnpm -F eslint-plugin-artalk exec tsc --noEmit && pnpm -F eslint-plugin-artalk test --run",
|
||||
"test:plugins:attw": "pnpm -F @artalk/plugin-* -F eslint-plugin-artalk test:attw",
|
||||
"build:typedoc": "pnpm typedoc",
|
||||
"build:docs": "pnpm build && pnpm build:plugins && pnpm -F=docs-landing build && pnpm -F=docs-swagger swagger:build && pnpm -F=docs build:docs && pnpm after:build-docs",
|
||||
"after:build-docs": "cp -rf docs/landing/dist/* docs/swagger/dist/* docs/docs/.vitepress/dist && pnpm build:typedoc && pnpm fetch:registry",
|
||||
|
||||
@@ -1,15 +1,34 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { promises as fs, readFileSync } from 'fs'
|
||||
import path from 'path'
|
||||
import { execFileSync } from 'child_process'
|
||||
import process from 'process'
|
||||
import { promises as fs, readFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const __dirname = path.dirname(new URL(import.meta.url).pathname)
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const REGISTRY_URL = 'https://registry.npmjs.org/'
|
||||
const REQUEST_TIMEOUT = 10_000
|
||||
|
||||
// Helper to run shell commands
|
||||
const getPublishedVersion = (packageName) =>
|
||||
execFileSync('pnpm', ['info', packageName, 'version'], { encoding: 'utf-8' }).trim()
|
||||
const getPublishedPackage = async (packageName) => {
|
||||
const packageUrl = new URL(encodeURIComponent(packageName), REGISTRY_URL)
|
||||
const response = await fetch(packageUrl, {
|
||||
headers: { Accept: 'application/vnd.npm.install-v1+json' },
|
||||
signal: AbortSignal.timeout(REQUEST_TIMEOUT),
|
||||
})
|
||||
|
||||
if (response.status === 404) {
|
||||
return { latestVersion: null, versions: new Set() }
|
||||
}
|
||||
if (!response.ok) {
|
||||
throw new Error(`npm registry returned HTTP ${response.status} for ${packageName}`)
|
||||
}
|
||||
|
||||
const packageMetadata = await response.json()
|
||||
return {
|
||||
latestVersion: packageMetadata['dist-tags']?.latest || null,
|
||||
versions: new Set(Object.keys(packageMetadata.versions || {})),
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively find all directories containing package.json
|
||||
const findNodeProjects = async (dir) => {
|
||||
@@ -36,8 +55,8 @@ const findNodeProjects = async (dir) => {
|
||||
return projects
|
||||
}
|
||||
|
||||
// Compare local version with the latest npm version
|
||||
const checkVersionMismatch = async (projectPath) => {
|
||||
// Check whether the exact local version has already been published to npm.
|
||||
const checkVersionPublished = async (projectPath) => {
|
||||
const packageJsonPath = path.join(projectPath, 'package.json')
|
||||
|
||||
try {
|
||||
@@ -46,23 +65,22 @@ const checkVersionMismatch = async (projectPath) => {
|
||||
const localVersion = packageJson.version
|
||||
const packageName = packageJson.name
|
||||
|
||||
// Get the latest version from npm using pnpm info
|
||||
const npmVersion = getPublishedVersion(packageName)
|
||||
const { latestVersion, versions } = await getPublishedPackage(packageName)
|
||||
|
||||
if (localVersion === npmVersion) {
|
||||
console.log(`✅ ${packageName} is up to date (${npmVersion})`)
|
||||
} else {
|
||||
console.log(`❌ ${packageName} is outdated (local: ${localVersion}, npm: ${npmVersion})`)
|
||||
if (versions.has(localVersion)) {
|
||||
const latestSuffix =
|
||||
localVersion === latestVersion ? '' : `; npm latest is ${latestVersion || 'unset'}`
|
||||
console.log(`✅ ${packageName}@${localVersion} is published${latestSuffix}`)
|
||||
return null
|
||||
}
|
||||
|
||||
if (localVersion !== npmVersion) {
|
||||
return { packageName, localVersion, latestVersion: npmVersion }
|
||||
}
|
||||
console.log(
|
||||
`❌ ${packageName}@${localVersion} is not published (npm latest: ${latestVersion || 'none'})`,
|
||||
)
|
||||
return { packageName, localVersion, latestVersion }
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to check npm version for ${projectPath}`, { cause: error })
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// Parse command-line arguments to get the project name if provided
|
||||
@@ -79,8 +97,8 @@ const getArgs = () => {
|
||||
return specifiedProject
|
||||
}
|
||||
|
||||
// Main function to find outdated packages
|
||||
const findOutdatedProjects = async () => {
|
||||
// Main function to find unpublished local package versions
|
||||
const findUnpublishedProjects = async () => {
|
||||
const specifiedProject = getArgs()
|
||||
let projects = await findNodeProjects(path.join(__dirname, '../ui'))
|
||||
console.log(`Found ${projects.length} projects under 'ui' directory.\n`)
|
||||
@@ -100,29 +118,29 @@ const findOutdatedProjects = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const outdatedProjects = []
|
||||
const unpublishedProjects = []
|
||||
|
||||
for (const project of projects) {
|
||||
const result = await checkVersionMismatch(project)
|
||||
const result = await checkVersionPublished(project)
|
||||
if (result) {
|
||||
outdatedProjects.push(result)
|
||||
unpublishedProjects.push(result)
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n==================================================\n')
|
||||
|
||||
if (outdatedProjects.length === 0) {
|
||||
console.log('✅ All projects have the latest versions pushed to npm.')
|
||||
if (unpublishedProjects.length === 0) {
|
||||
console.log('✅ Every local package version is published to npm.')
|
||||
} else {
|
||||
console.log('Projects with outdated versions:\n')
|
||||
outdatedProjects.forEach(({ packageName, localVersion, latestVersion }) => {
|
||||
console.log(`❌ ${packageName}: Local version ${localVersion}, NPM version ${latestVersion}`)
|
||||
console.log('Local package versions not published to npm:\n')
|
||||
unpublishedProjects.forEach(({ packageName, localVersion, latestVersion }) => {
|
||||
console.log(`❌ ${packageName}: local ${localVersion}, npm latest ${latestVersion || 'none'}`)
|
||||
})
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
findOutdatedProjects().catch((error) => {
|
||||
findUnpublishedProjects().catch((error) => {
|
||||
console.error(error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
@@ -4,6 +4,12 @@
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/ArtalkJS/Artalk/tree/master/ui/eslint-plugin-artalk",
|
||||
"bugs": "https://github.com/ArtalkJS/Artalk/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ArtalkJS/Artalk.git",
|
||||
"directory": "ui/eslint-plugin-artalk"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
@@ -24,7 +30,8 @@
|
||||
"scripts": {
|
||||
"dev": "tsdown --watch",
|
||||
"build": "tsdown",
|
||||
"test": "vitest"
|
||||
"test": "vitest",
|
||||
"test:attw": "pnpx @arethetypeswrong/cli@0.18.5 --pack ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/utils": "^8.65.0"
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
{
|
||||
"name": "@artalk/plugin-auth",
|
||||
"version": "0.0.3",
|
||||
"minAppVersion": "2.10.0",
|
||||
"license": "LGPL-3.0-only",
|
||||
"description": "Auth plugin for artalk",
|
||||
"homepage": "https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-auth",
|
||||
"bugs": "https://github.com/ArtalkJS/Artalk/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ArtalkJS/Artalk.git",
|
||||
"directory": "ui/plugin-auth"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"type": "module",
|
||||
"files": [
|
||||
"dist"
|
||||
@@ -12,15 +23,21 @@
|
||||
"types": "./dist/artalk-plugin-auth.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/artalk-plugin-auth.d.ts",
|
||||
"import": "./dist/artalk-plugin-auth.mjs",
|
||||
"require": "./dist/artalk-plugin-auth.cjs"
|
||||
"import": {
|
||||
"types": "./dist/artalk-plugin-auth.d.ts",
|
||||
"default": "./dist/artalk-plugin-auth.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/artalk-plugin-auth.d.cts",
|
||||
"default": "./dist/artalk-plugin-auth.cjs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"serve": "vite preview"
|
||||
"serve": "vite preview",
|
||||
"test:attw": "pnpx @arethetypeswrong/cli@0.18.5 --pack ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@artalk/plugin-kit": "workspace:^",
|
||||
@@ -30,6 +47,6 @@
|
||||
"vite-plugin-solid": "^2.11.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"artalk": "workspace:^"
|
||||
"artalk": "^2.10.0"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import type { ArtalkPlugin } from 'artalk'
|
||||
|
||||
declare const ArtalkAuthPlugin: ArtalkPlugin
|
||||
@@ -1,3 +0,0 @@
|
||||
import type { ArtalkPlugin } from 'artalk'
|
||||
|
||||
declare const ArtalkAuthPlugin: ArtalkPlugin
|
||||
@@ -1,8 +1,19 @@
|
||||
{
|
||||
"name": "@artalk/plugin-katex",
|
||||
"version": "0.2.5",
|
||||
"minAppVersion": "2.8.6",
|
||||
"license": "MIT",
|
||||
"description": "The katex plugin for artalk",
|
||||
"homepage": "https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-katex",
|
||||
"bugs": "https://github.com/ArtalkJS/Artalk/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ArtalkJS/Artalk.git",
|
||||
"directory": "ui/plugin-katex"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "./dist/artalk-plugin-katex.js",
|
||||
"module": "./dist/artalk-plugin-katex.mjs",
|
||||
@@ -13,7 +24,8 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"serve": "vite preview"
|
||||
"serve": "vite preview",
|
||||
"test:attw": "pnpx @arethetypeswrong/cli@0.18.5 --pack ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@artalk/plugin-kit": "workspace:^",
|
||||
@@ -22,14 +34,19 @@
|
||||
"marked": "^18.0.7"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"artalk": "workspace:^",
|
||||
"artalk": ">=2.8.6 <3.0.0",
|
||||
"katex": ">=0.16.45 <0.18.0"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/artalk-plugin-katex.d.ts",
|
||||
"import": "./dist/artalk-plugin-katex.mjs",
|
||||
"require": "./dist/artalk-plugin-katex.cjs"
|
||||
"import": {
|
||||
"types": "./dist/artalk-plugin-katex.d.ts",
|
||||
"default": "./dist/artalk-plugin-katex.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/artalk-plugin-katex.d.cts",
|
||||
"default": "./dist/artalk-plugin-katex.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import Artalk from 'artalk'
|
||||
|
||||
export {}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
Artalk?: typeof Artalk
|
||||
}
|
||||
}
|
||||
Vendored
+1
-2
@@ -1,10 +1,9 @@
|
||||
import Artalk, { ArtalkPlugin } from 'artalk'
|
||||
import Artalk from 'artalk'
|
||||
|
||||
export {}
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
Artalk?: typeof Artalk
|
||||
ArtalkPlugins?: { [name: string]: ArtalkPlugin }
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,16 @@
|
||||
"name": "@artalk/plugin-kit",
|
||||
"version": "1.0.9",
|
||||
"description": "The plugin kit for Artalk",
|
||||
"homepage": "https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-kit",
|
||||
"bugs": "https://github.com/ArtalkJS/Artalk/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ArtalkJS/Artalk.git",
|
||||
"directory": "ui/plugin-kit"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "dist/main.cjs",
|
||||
"types": "dist/main.d.cts",
|
||||
@@ -16,15 +26,32 @@
|
||||
"default": "./dist/main.mjs"
|
||||
}
|
||||
},
|
||||
"./client": "./client.d.ts"
|
||||
"./client": {
|
||||
"import": {
|
||||
"types": "./client.d.ts"
|
||||
},
|
||||
"require": {
|
||||
"types": "./client.d.cts"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "tsdown --watch",
|
||||
"build": "tsdown"
|
||||
"build": "tsdown",
|
||||
"test:attw": "pnpx @arethetypeswrong/cli@0.18.5 --pack ."
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist/**/*.cjs",
|
||||
"dist/**/*.mjs",
|
||||
"dist/**/*.map",
|
||||
"dist/**/*.d.cts",
|
||||
"dist/**/*.d.mts",
|
||||
"client.d.ts",
|
||||
"client.d.cts"
|
||||
],
|
||||
"dependencies": {
|
||||
"@microsoft/api-extractor": "^7.58.12",
|
||||
"picocolors": "^1.1.1"
|
||||
@@ -35,7 +62,7 @@
|
||||
"vite": "^8.1.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"artalk": "workspace:^",
|
||||
"artalk": "^2.10.0",
|
||||
"typescript": "*",
|
||||
"vite": "*"
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -1,5 +1,4 @@
|
||||
interface Window {
|
||||
lightGallery: (el: any, options: any) => any | undefined
|
||||
Fancybox?: any
|
||||
lightbox?: any
|
||||
PhotoSwipeLightbox?: any
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
{
|
||||
"name": "@artalk/plugin-lightbox",
|
||||
"version": "0.2.5",
|
||||
"minAppVersion": "2.9.1",
|
||||
"license": "MIT",
|
||||
"description": "The image lightbox plugin for artalk",
|
||||
"homepage": "https://github.com/ArtalkJS/Artalk/tree/master/ui/plugin-lightbox",
|
||||
"bugs": "https://github.com/ArtalkJS/Artalk/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ArtalkJS/Artalk.git",
|
||||
"directory": "ui/plugin-lightbox"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "./dist/artalk-plugin-lightbox.js",
|
||||
"module": "./dist/artalk-plugin-lightbox.mjs",
|
||||
@@ -13,7 +24,8 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"serve": "vite preview"
|
||||
"serve": "vite preview",
|
||||
"test:attw": "pnpx @arethetypeswrong/cli@0.18.5 --pack ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@artalk/plugin-kit": "workspace:^",
|
||||
@@ -24,7 +36,7 @@
|
||||
"photoswipe": "^5.4.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"artalk": "workspace:^",
|
||||
"artalk": "^2.9.1",
|
||||
"fancybox": "^3.0.1",
|
||||
"lightbox2": "^2.12.0",
|
||||
"lightgallery": "^2.9.0",
|
||||
@@ -46,9 +58,14 @@
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/artalk-plugin-lightbox.d.ts",
|
||||
"import": "./dist/artalk-plugin-lightbox.mjs",
|
||||
"require": "./dist/artalk-plugin-lightbox.cjs"
|
||||
"import": {
|
||||
"types": "./dist/artalk-plugin-lightbox.d.ts",
|
||||
"default": "./dist/artalk-plugin-lightbox.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/artalk-plugin-lightbox.d.cts",
|
||||
"default": "./dist/artalk-plugin-lightbox.cjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user