name: Package component on: push: tags: - 'v*' jobs: package: runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Check out repository shell: bash run: | set -euo pipefail server_url="${{ gitea.server_url }}" repository_url="${server_url%/}/${{ gitea.repository }}.git" tag_name="${{ gitea.ref_name }}" git init . git remote add origin "$repository_url" git fetch --depth 1 origin "refs/tags/$tag_name:refs/tags/$tag_name" git checkout --detach "$tag_name^{commit}" - name: Set up pnpm run: | corepack enable corepack prepare pnpm@10.32.1 --activate - name: Install dependencies run: pnpm install --frozen-lockfile - name: Validate release version shell: bash run: | set -euo pipefail tag_name="${{ gitea.ref_name }}" tag_pattern='^v([0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?)$' if [[ ! "$tag_name" =~ $tag_pattern ]]; then echo "Release tags must use vX.Y.Z or vX.Y.Z-prerelease format: $tag_name" >&2 exit 1 fi package_version="${BASH_REMATCH[1]}" source_version="$(node -p "require('./package.json').version")" if [[ "$source_version" != "$package_version" ]]; then echo "package.json version $source_version does not match tag $tag_name" >&2 exit 1 fi if [[ "$package_version" == *-* ]]; then npm_dist_tag='next' is_prerelease='true' else npm_dist_tag='latest' is_prerelease='false' fi cat > release.env <&2 exit 1 fi package_metadata="$(curl --fail --show-error --silent "$registry_url$package_name")" if node -e 'const chunks = []; process.stdin.on("data", chunk => chunks.push(chunk)); process.stdin.on("end", () => { const metadata = JSON.parse(Buffer.concat(chunks).toString()); process.exit(metadata.versions?.[process.argv[1]] ? 0 : 1) })' "$PACKAGE_VERSION" <<<"$package_metadata"; then echo "npm package $package_name@$PACKAGE_VERSION already exists" >&2 exit 1 fi - name: Validate publish credentials shell: bash env: NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} run: | set -euo pipefail : "${NODE_AUTH_TOKEN:?NPM_PUBLISH_TOKEN is required}" : "${RELEASE_TOKEN:?RELEASE_TOKEN is required}" - name: Type check run: pnpm typecheck - name: Lint run: pnpm lint - name: Test with coverage run: pnpm test:coverage - name: Build component run: pnpm build - name: Pack component shell: bash run: | set -euo pipefail source release.env pnpm pack --pack-destination artifacts package_file="$(find artifacts -maxdepth 1 -type f -name '*.tgz' -print -quit)" test -n "$package_file" mkdir -p release-assets published_name="waveform-analysis-${PACKAGE_VERSION}.tgz" install -m 644 "$package_file" "release-assets/$published_name" sha256sum "release-assets/$published_name" > "release-assets/$published_name.sha256" - name: Verify component package shell: bash run: | set -euo pipefail source release.env package_file="release-assets/waveform-analysis-${PACKAGE_VERSION}.tgz" test -f "$package_file" package_contents="$(tar -tzf "$package_file")" for required_file in \ package/dist/index.js \ package/dist/index.cjs \ package/dist/types/index.d.ts \ package/dist/style.css \ package/src/index.ts \ package/src/components/WaveformChart.vue \ package/package.json \ package/README.md; do grep -Fxq "$required_file" <<< "$package_contents" done - name: Publish component package shell: bash run: | set -euo pipefail source release.env published_name="waveform-analysis-${PACKAGE_VERSION}.tgz" install -m 644 "release-assets/$published_name" "/downloads/$published_name" cd /downloads sha256sum "$published_name" > "$published_name.sha256" if [[ "$IS_PRERELEASE" == 'false' ]]; then ln -sfn "$published_name" waveform-analysis-latest.tgz ln -sfn "$published_name.sha256" waveform-analysis-latest.tgz.sha256 fi - name: Publish to Gitea npm registry shell: bash env: NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }} run: | set -euo pipefail source release.env : "${NODE_AUTH_TOKEN:?NPM_PUBLISH_TOKEN is required}" registry_url='https://lqycustomsite.online/api/packages/admin/npm/' package_file="release-assets/waveform-analysis-${PACKAGE_VERSION}.tgz" npm config set -- '//lqycustomsite.online/api/packages/admin/npm/:_authToken' "$NODE_AUTH_TOKEN" npm publish "$package_file" --registry="$registry_url" --tag "$NPM_DIST_TAG" - name: Create Gitea release shell: bash env: RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} run: | set -euo pipefail source release.env : "${RELEASE_TOKEN:?RELEASE_TOKEN is required}" server_url="${{ gitea.server_url }}" api_url="$server_url/api/v1/repos/${{ gitea.repository }}/releases" target_commitish="$(git rev-parse HEAD)" node - "$TAG_NAME" "$PACKAGE_VERSION" "$target_commitish" "$IS_PRERELEASE" > release.json <<'NODE' const [tagName, packageVersion, targetCommitish, prerelease] = process.argv.slice(2) process.stdout.write(JSON.stringify({ tag_name: tagName, target_commitish: targetCommitish, name: `waveform-analysis ${tagName}`, body: `Release ${tagName}\n\n- npm: waveform-analysis@${packageVersion}`, draft: false, prerelease: prerelease === 'true', })) NODE release_response="$(curl --fail --show-error --silent \ --request POST \ --header "Authorization: token $RELEASE_TOKEN" \ --header 'Content-Type: application/json' \ --data @release.json \ "$api_url")" release_id="$(node -e 'const chunks = []; process.stdin.on("data", chunk => chunks.push(chunk)); process.stdin.on("end", () => { const release = JSON.parse(Buffer.concat(chunks).toString()); if (!release.id) process.exit(1); process.stdout.write(String(release.id)) })' <<<"$release_response")" for asset in release-assets/*; do asset_name="$(basename "$asset")" curl --fail --show-error --silent \ --request POST \ --header "Authorization: token $RELEASE_TOKEN" \ --header 'Content-Type: application/octet-stream' \ --data-binary "@$asset" \ "$api_url/$release_id/assets?name=$asset_name" > /dev/null done