feat: add npm publish workflow with Trusted Publishing
This commit is contained in:
55
.github/workflows/publish.yml
vendored
Normal file
55
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
name: publish
|
||||||
|
run-name: "${{ format('release {0}', inputs.bump) }}"
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
bump:
|
||||||
|
description: "Bump major, minor, or patch"
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- major
|
||||||
|
- minor
|
||||||
|
- patch
|
||||||
|
version:
|
||||||
|
description: "Override version (optional)"
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- run: git fetch --force --tags
|
||||||
|
|
||||||
|
- uses: oven-sh/setup-bun@v2
|
||||||
|
with:
|
||||||
|
bun-version: latest
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: "20"
|
||||||
|
registry-url: "https://registry.npmjs.org"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: bun install
|
||||||
|
|
||||||
|
- name: Publish
|
||||||
|
run: ./script/publish.ts
|
||||||
|
env:
|
||||||
|
BUMP: ${{ inputs.bump }}
|
||||||
|
VERSION: ${{ inputs.version }}
|
||||||
|
CI: true
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
NPM_CONFIG_PROVENANCE: true
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "oh-my-opencode",
|
"name": "oh-my-opencode",
|
||||||
"version": "0.1.0",
|
"version": "0.0.0",
|
||||||
"description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
|
"description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
|
|||||||
105
script/publish.ts
Normal file
105
script/publish.ts
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#!/usr/bin/env bun
|
||||||
|
|
||||||
|
import { $ } from "bun"
|
||||||
|
|
||||||
|
const PACKAGE_NAME = "oh-my-opencode"
|
||||||
|
const bump = process.env.BUMP as "major" | "minor" | "patch" | undefined
|
||||||
|
const versionOverride = process.env.VERSION
|
||||||
|
|
||||||
|
console.log("=== Publishing oh-my-opencode ===\n")
|
||||||
|
|
||||||
|
async function fetchPreviousVersion(): Promise<string> {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`)
|
||||||
|
if (!res.ok) throw new Error(`Failed to fetch: ${res.statusText}`)
|
||||||
|
const data = (await res.json()) as { version: string }
|
||||||
|
console.log(`Previous version: ${data.version}`)
|
||||||
|
return data.version
|
||||||
|
} catch {
|
||||||
|
console.log("No previous version found, starting from 0.0.0")
|
||||||
|
return "0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bumpVersion(version: string, type: "major" | "minor" | "patch"): string {
|
||||||
|
const [major, minor, patch] = version.split(".").map(Number)
|
||||||
|
switch (type) {
|
||||||
|
case "major":
|
||||||
|
return `${major + 1}.0.0`
|
||||||
|
case "minor":
|
||||||
|
return `${major}.${minor + 1}.0`
|
||||||
|
case "patch":
|
||||||
|
return `${major}.${minor}.${patch + 1}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updatePackageVersion(newVersion: string): Promise<void> {
|
||||||
|
const pkgPath = new URL("../package.json", import.meta.url).pathname
|
||||||
|
let pkg = await Bun.file(pkgPath).text()
|
||||||
|
pkg = pkg.replace(/"version": "[^"]+"/, `"version": "${newVersion}"`)
|
||||||
|
await Bun.file(pkgPath).write(pkg)
|
||||||
|
console.log(`Updated: ${pkgPath}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function generateChangelog(previous: string): Promise<string> {
|
||||||
|
try {
|
||||||
|
const log = await $`git log v${previous}..HEAD --oneline --format="%h %s"`.text()
|
||||||
|
const commits = log
|
||||||
|
.split("\n")
|
||||||
|
.filter((line) => line && !line.match(/^\w+ (ignore:|test:|chore:|ci:|release:)/i))
|
||||||
|
|
||||||
|
if (commits.length > 0) {
|
||||||
|
const changelog = commits.map((c) => `- ${c}`).join("\n")
|
||||||
|
console.log("\n--- Changelog ---")
|
||||||
|
console.log(changelog)
|
||||||
|
console.log("-----------------\n")
|
||||||
|
return changelog
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
console.log("No previous tags found, skipping changelog generation")
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
async function buildAndPublish(): Promise<void> {
|
||||||
|
console.log("Building...")
|
||||||
|
await $`bun run build`
|
||||||
|
|
||||||
|
console.log("\nPublishing to npm...")
|
||||||
|
if (process.env.CI) {
|
||||||
|
await $`npm publish --access public --provenance`
|
||||||
|
} else {
|
||||||
|
await $`npm publish --access public`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function gitTagAndRelease(newVersion: string, changelog: string): Promise<void> {
|
||||||
|
if (!process.env.CI) return
|
||||||
|
|
||||||
|
console.log("\nCommitting and tagging...")
|
||||||
|
await $`git config user.email "github-actions[bot]@users.noreply.github.com"`
|
||||||
|
await $`git config user.name "github-actions[bot]"`
|
||||||
|
await $`git add package.json`
|
||||||
|
await $`git commit -m "release: v${newVersion}"`
|
||||||
|
await $`git tag v${newVersion}`
|
||||||
|
await $`git push origin HEAD --tags`
|
||||||
|
|
||||||
|
console.log("\nCreating GitHub release...")
|
||||||
|
const releaseNotes = changelog || "No notable changes"
|
||||||
|
await $`gh release create v${newVersion} --title "v${newVersion}" --notes ${releaseNotes}`
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const previous = await fetchPreviousVersion()
|
||||||
|
const newVersion = versionOverride || (bump ? bumpVersion(previous, bump) : bumpVersion(previous, "patch"))
|
||||||
|
console.log(`New version: ${newVersion}\n`)
|
||||||
|
|
||||||
|
await updatePackageVersion(newVersion)
|
||||||
|
const changelog = await generateChangelog(previous)
|
||||||
|
await buildAndPublish()
|
||||||
|
await gitTagAndRelease(newVersion, changelog)
|
||||||
|
|
||||||
|
console.log(`\n=== Successfully published ${PACKAGE_NAME}@${newVersion} ===`)
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user