Skip to content

Commit ac99185

Browse files
authored
chore: release v0.2.1 (#1896)
2 parents 84ba3d0 + 504e448 commit ac99185

File tree

22 files changed

+476
-143
lines changed

22 files changed

+476
-143
lines changed

.github/workflows/release-pr.yml

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ jobs:
2020
with:
2121
fetch-depth: 0
2222

23+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
24+
with:
25+
node-version: lts/*
26+
2327
- name: 🔍 Check for unreleased commits
2428
id: check
2529
run: |
@@ -34,21 +38,26 @@ jobs:
3438
echo "$COMMITS"
3539
fi
3640
41+
- name: 🔢 Determine next version
42+
if: steps.check.outputs.skip == 'false'
43+
id: version
44+
run: |
45+
VERSION_JSON=$(node scripts/next-version.ts)
46+
CURRENT_VERSION=$(echo "$VERSION_JSON" | jq -r .current)
47+
NEXT_VERSION=$(echo "$VERSION_JSON" | jq -r .next)
48+
FROM_REF=$(echo "$VERSION_JSON" | jq -r .from)
49+
echo "current=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
50+
echo "next=v${NEXT_VERSION}" >> "$GITHUB_OUTPUT"
51+
echo "from=$FROM_REF" >> "$GITHUB_OUTPUT"
52+
3753
- name: 📝 Generate changelog body
3854
if: steps.check.outputs.skip == 'false'
3955
id: changelog
56+
env:
57+
CURRENT_VERSION: ${{ steps.version.outputs.current }}
58+
NEXT_VERSION: ${{ steps.version.outputs.next }}
59+
FROM_REF: ${{ steps.version.outputs.from }}
4060
run: |
41-
# Get the latest tag, or use initial commit if no tags exist
42-
LATEST_TAG=$(git describe --tags --abbrev=0 origin/release 2>/dev/null || echo "")
43-
44-
if [ -z "$LATEST_TAG" ]; then
45-
FROM_REF=$(git rev-list --max-parents=0 HEAD)
46-
CURRENT_VERSION="0.0.0"
47-
else
48-
FROM_REF="$LATEST_TAG"
49-
CURRENT_VERSION="${LATEST_TAG#v}"
50-
fi
51-
5261
# Categorize commits
5362
FEATURES=""
5463
FIXES=""
@@ -72,25 +81,12 @@ jobs:
7281
fi
7382
done <<< "$(git log "$FROM_REF"..origin/main --oneline --no-merges)"
7483
75-
# Determine next version
76-
HAS_BREAKING=$(git log "$FROM_REF"..origin/main --format='%B' | grep -c 'BREAKING CHANGE\|!:' || true)
77-
HAS_FEAT=$(git log "$FROM_REF"..origin/main --oneline --no-merges | grep -cE '^[a-f0-9]+ feat(\(|:)' || true)
78-
79-
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
80-
81-
if [ "$HAS_BREAKING" -gt 0 ] && [ "$MAJOR" -gt 0 ]; then
82-
NEXT_VERSION="$((MAJOR + 1)).0.0"
83-
elif [ "$HAS_FEAT" -gt 0 ]; then
84-
NEXT_VERSION="${MAJOR}.$((MINOR + 1)).0"
85-
else
86-
NEXT_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
87-
fi
88-
89-
echo "next_version=v${NEXT_VERSION}" >> "$GITHUB_OUTPUT"
84+
# Strip the leading 'v' for display
85+
DISPLAY_NEXT="${NEXT_VERSION#v}"
9086
9187
# Build the PR body
9288
BODY="This PR will deploy the following changes to production (\`npmx.dev\`).\n\n"
93-
BODY="${BODY}**Next version: \`v${NEXT_VERSION}\`** (current: \`v${CURRENT_VERSION}\`)\n\n"
89+
BODY="${BODY}**Next version: \`${NEXT_VERSION}\`** (current: \`v${CURRENT_VERSION}\`)\n\n"
9490
9591
if [ -n "$FEATURES" ]; then
9692
BODY="${BODY}### Features\n\n${FEATURES}\n"
@@ -108,31 +104,31 @@ jobs:
108104
BODY="${BODY}---\n\n"
109105
BODY="${BODY}> Merging this PR will:\n"
110106
BODY="${BODY}> - Deploy to \`npmx.dev\` via Vercel\n"
111-
BODY="${BODY}> - Create a \`v${NEXT_VERSION}\` tag and GitHub Release\n"
112-
BODY="${BODY}> - Publish \`npmx-connector@${NEXT_VERSION}\` to npm"
107+
BODY="${BODY}> - Create a \`${NEXT_VERSION}\` tag and GitHub Release\n"
108+
BODY="${BODY}> - Publish \`npmx-connector@${DISPLAY_NEXT}\` to npm"
113109
114110
# Write body to file, truncating if needed (GitHub limits PR body to 65536 chars)
115111
echo -e "$BODY" > /tmp/pr-body.md
116112
if [ "$(wc -c < /tmp/pr-body.md)" -gt 60000 ]; then
117113
COMMIT_COUNT=$(git log "$FROM_REF"..origin/main --oneline --no-merges | wc -l)
118114
COMPARE_URL="https://github.com/npmx-dev/npmx.dev/compare/${FROM_REF}...main"
119115
TRUNCATED="This PR will deploy the following changes to production (\`npmx.dev\`).\n\n"
120-
TRUNCATED="${TRUNCATED}**Next version: \`v${NEXT_VERSION}\`** (current: \`v${CURRENT_VERSION}\`)\n\n"
116+
TRUNCATED="${TRUNCATED}**Next version: \`${NEXT_VERSION}\`** (current: \`v${CURRENT_VERSION}\`)\n\n"
121117
TRUNCATED="${TRUNCATED}> **${COMMIT_COUNT} commits** are included in this release. The full changelog is too large to display here.\n>\n"
122118
TRUNCATED="${TRUNCATED}> [View full diff on GitHub](${COMPARE_URL})\n\n"
123119
TRUNCATED="${TRUNCATED}---\n\n"
124120
TRUNCATED="${TRUNCATED}> Merging this PR will:\n"
125121
TRUNCATED="${TRUNCATED}> - Deploy to \`npmx.dev\` via Vercel\n"
126-
TRUNCATED="${TRUNCATED}> - Create a \`v${NEXT_VERSION}\` tag and GitHub Release\n"
127-
TRUNCATED="${TRUNCATED}> - Publish \`npmx-connector@${NEXT_VERSION}\` to npm"
122+
TRUNCATED="${TRUNCATED}> - Create a \`${NEXT_VERSION}\` tag and GitHub Release\n"
123+
TRUNCATED="${TRUNCATED}> - Publish \`npmx-connector@${DISPLAY_NEXT}\` to npm"
128124
echo -e "$TRUNCATED" > /tmp/pr-body.md
129125
fi
130126
131127
- name: 🚀 Create or update release PR
132128
if: steps.check.outputs.skip == 'false'
133129
env:
134130
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
135-
NEXT_VERSION: ${{ steps.changelog.outputs.next_version }}
131+
NEXT_VERSION: ${{ steps.version.outputs.next }}
136132
run: |
137133
EXISTING_PR=$(gh pr list --base release --head main --state open --json number --jq '.[0].number')
138134

.github/workflows/release-tag.yml

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,18 @@ jobs:
2323
with:
2424
fetch-depth: 0
2525

26+
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
27+
with:
28+
node-version: lts/*
29+
2630
- name: 🔢 Determine next version
2731
id: version
2832
run: |
29-
# Get the latest tag on this branch
30-
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
31-
32-
if [ -z "$LATEST_TAG" ]; then
33-
CURRENT_VERSION="0.0.0"
34-
FROM_REF=$(git rev-list --max-parents=0 HEAD)
35-
else
36-
CURRENT_VERSION="${LATEST_TAG#v}"
37-
FROM_REF="$LATEST_TAG"
38-
fi
39-
40-
# Analyze conventional commits since last tag
41-
HAS_BREAKING=$(git log "${FROM_REF}..HEAD" --format='%B' | grep -c 'BREAKING CHANGE\|!:' || true)
42-
HAS_FEAT=$(git log "${FROM_REF}..HEAD" --oneline --no-merges | grep -cE '^[a-f0-9]+ feat(\(|:)' || true)
43-
HAS_FIX=$(git log "${FROM_REF}..HEAD" --oneline --no-merges | grep -cE '^[a-f0-9]+ fix(\(|:)' || true)
44-
45-
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
46-
47-
if [ "$HAS_BREAKING" -gt 0 ] && [ "$MAJOR" -gt 0 ]; then
48-
NEXT_VERSION="$((MAJOR + 1)).0.0"
49-
elif [ "$HAS_FEAT" -gt 0 ]; then
50-
NEXT_VERSION="${MAJOR}.$((MINOR + 1)).0"
51-
elif [ "$HAS_FIX" -gt 0 ]; then
52-
NEXT_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
53-
else
54-
# Only chore/docs/ci commits — still bump patch
55-
NEXT_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
56-
fi
57-
58-
echo "current=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
59-
echo "next=v${NEXT_VERSION}" >> "$GITHUB_OUTPUT"
60-
echo "from=$FROM_REF" >> "$GITHUB_OUTPUT"
61-
echo "Bumping from v${CURRENT_VERSION} to v${NEXT_VERSION}"
33+
VERSION_JSON=$(node scripts/next-version.ts)
34+
echo "current=$(echo "$VERSION_JSON" | jq -r .current)" >> "$GITHUB_OUTPUT"
35+
echo "next=v$(echo "$VERSION_JSON" | jq -r .next)" >> "$GITHUB_OUTPUT"
36+
echo "from=$(echo "$VERSION_JSON" | jq -r .from)" >> "$GITHUB_OUTPUT"
37+
echo "Bumping from v$(echo "$VERSION_JSON" | jq -r .current) to v$(echo "$VERSION_JSON" | jq -r .next)"
6238
6339
- name: 🔍 Check if tag already exists
6440
id: check
@@ -82,11 +58,6 @@ jobs:
8258
git tag -a "$VERSION" -m "Release $VERSION"
8359
git push origin "$VERSION"
8460
85-
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
86-
if: steps.check.outputs.skip == 'false'
87-
with:
88-
node-version: lts/*
89-
9061
- uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # 4e1c8eafbd745f64b1ef30a7d7ed7965034c486c
9162
if: steps.check.outputs.skip == 'false'
9263
name: 🟧 Install pnpm
Lines changed: 6 additions & 0 deletions
Loading

app/assets/logos/oss-partners/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import LogoLunaria from './lunaria.svg'
3030
import LogoJsr from './jsr.svg'
3131
import LogoIconify from './iconify.svg'
3232
import LogoFloatingUi from './floating-ui-vue.svg'
33+
import LogoBlento from './blento.svg'
3334

3435
// The list is used on the about page. To add, simply upload the logos nearby and add an entry here. Prefer SVGs.
3536
// For logo src, specify a string or object with the light and dark theme variants.
@@ -195,4 +196,9 @@ export const OSS_PARTNERS = [
195196
logo: LogoFloatingUi,
196197
url: 'https://floating-ui.com/',
197198
},
199+
{
200+
name: 'blento',
201+
logo: LogoBlento,
202+
url: 'https://blento.app/npmx.dev',
203+
},
198204
]

app/components/global/BlogPostWrapper.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import type { BlogPostFrontmatter } from '#shared/schemas/blog'
3+
import { generateBlogTID } from '#shared/utils/atproto'
34
45
const props = defineProps<{
56
frontmatter: BlogPostFrontmatter
@@ -14,6 +15,15 @@ useSeoMeta({
1415
...(props.frontmatter.draft ? { robots: 'noindex, nofollow' } : {}),
1516
})
1617
18+
useHead({
19+
link: [
20+
{
21+
rel: 'site.standard.document',
22+
href: `at://${NPMX_DEV_DID}/site.standard.document/${generateBlogTID(props.frontmatter.date, props.frontmatter.slug)}`,
23+
},
24+
],
25+
})
26+
1727
defineOgImageComponent('BlogPost', {
1828
title: props.frontmatter.title,
1929
authors: props.frontmatter.authors,

app/pages/blog/alpha-release.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ headline="Read more from the community"
101101
authorHandle: 'patak.cat',
102102
description: 'The story of the many people and communities that converged to build npmx together.'
103103
},
104+
{
105+
url: 'https://www.freecodecamp.org/news/learning-to-enjoy-code-reviews-with-npmx/',
106+
title: 'OSS Pull Request Therapy: Learning to Enjoy Code Reviews with npmx',
107+
authorHandle: 'abbeyperini.dev',
108+
description: 'For years, I thought Open Source Software (OSS) just wasn\'t for me. Curious about the hype I saw on Bluesky, I recently joined the npmx Discord server on a whim. My journey from lurker to contributor taught me a lot about OSS and gave me new confidence going into code reviews.'
109+
},
104110
{
105111
url: 'https://graphieros.github.io/graphieros-blog/blog/2026/npmx.html',
106112
title: 'vue-data-ui is on npmx npmx is on vue-data-ui',

config/env.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Git from 'simple-git'
44
import * as process from 'node:process'
55

66
import { version as packageVersion } from '../package.json'
7+
import { getNextVersion } from '../scripts/next-version'
78

89
export { packageVersion as version }
910

@@ -44,13 +45,15 @@ export const gitBranch = process.env.BRANCH || process.env.VERCEL_GIT_COMMIT_REF
4445
* Whether this is the canary environment (main.npmx.dev).
4546
*
4647
* Detected as any non-PR Vercel deploy from the `main` branch
47-
* (which may receive `VERCEL_ENV === 'production'` or `'preview'`
48-
* depending on the project's production branch configuration).
48+
* (which may receive `VERCEL_ENV === 'production'`, `'preview'`, or a
49+
* custom `'canary'` environment depending on the project configuration).
4950
*
5051
* @see {@link https://vercel.com/docs/environment-variables/system-environment-variables#VERCEL_ENV}
5152
*/
5253
export const isCanary =
53-
(process.env.VERCEL_ENV === 'production' || process.env.VERCEL_ENV === 'preview') &&
54+
(process.env.VERCEL_ENV === 'production' ||
55+
process.env.VERCEL_ENV === 'preview' ||
56+
process.env.VERCEL_ENV === 'canary') &&
5457
gitBranch === 'main' &&
5558
!isPR
5659

@@ -157,15 +160,17 @@ export async function getFileLastUpdated(path: string) {
157160
}
158161

159162
/**
160-
* Resolves the current version from git tags, falling back to `package.json`.
163+
* Resolves the **next** version by analysing conventional commits since the
164+
* last reachable `v*` tag. Delegates to {@link getNextVersion} which is also
165+
* used by the `release-tag` and `release-pr` GitHub Actions workflows so the
166+
* version shown in the UI matches the tag that will be created *after* deploy.
161167
*
162-
* Uses `git describe --tags --abbrev=0 --match 'v*'` to find the most recent
163-
* reachable release tag (e.g. `v0.1.0` -> `0.1.0`).
168+
* Falls back to `package.json` when git is unavailable (e.g. shallow clone).
164169
*/
165170
export async function getVersion() {
166171
try {
167-
const tag = (await git.raw(['describe', '--tags', '--abbrev=0', '--match', 'v*'])).trim()
168-
return tag.replace(/^v/, '')
172+
const { next } = await getNextVersion()
173+
return next
169174
} catch {
170175
return packageVersion
171176
}

0 commit comments

Comments
 (0)