mirror of
https://github.com/aljazceru/opencode.git
synced 2026-01-04 16:34:55 +01:00
ci: scripts
This commit is contained in:
15
script/hooks
Executable file
15
script/hooks
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -d ".git" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p .git/hooks
|
||||
|
||||
cat > .git/hooks/pre-push << 'EOF'
|
||||
#!/bin/sh
|
||||
bun run typecheck
|
||||
EOF
|
||||
|
||||
chmod +x .git/hooks/pre-push
|
||||
echo "✅ Pre-push hook installed"
|
||||
16
script/hooks.bat
Normal file
16
script/hooks.bat
Normal file
@@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
|
||||
if not exist ".git" (
|
||||
exit /b 0
|
||||
)
|
||||
|
||||
if not exist ".git\hooks" (
|
||||
mkdir ".git\hooks"
|
||||
)
|
||||
|
||||
(
|
||||
echo #!/bin/sh
|
||||
echo bun run typecheck
|
||||
) > ".git\hooks\pre-push"
|
||||
|
||||
echo ✅ Pre-push hook installed
|
||||
28
script/publish.ts
Executable file
28
script/publish.ts
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { $ } from "bun"
|
||||
|
||||
const snapshot = process.env["OPENCODE_SNAPSHOT"] === "true"
|
||||
const version = snapshot
|
||||
? `0.0.0-${new Date().toISOString().slice(0, 16).replace(/[-:T]/g, "")}`
|
||||
: process.env["OPENCODE_VERSION"]
|
||||
if (!version) {
|
||||
throw new Error("OPENCODE_VERSION is required")
|
||||
}
|
||||
process.env["OPENCODE_VERSION"] = version
|
||||
|
||||
await import(`../packages/opencode/script/publish.ts`)
|
||||
await import(`../packages/sdk/stainless/generate.ts`)
|
||||
await import(`../packages/sdk/js/script/publish.ts`)
|
||||
|
||||
if (!snapshot) {
|
||||
await $`git commit -am "Release v${version}"`
|
||||
await $`git tag v${version}`
|
||||
await $`git push origin HEAD --tags`
|
||||
}
|
||||
if (snapshot) {
|
||||
await $`git commit --allow-empty -m "Snapshot release v${version}"`
|
||||
await $`git tag v${version}`
|
||||
await $`git push origin v${version}`
|
||||
await $`git reset --soft HEAD~1`
|
||||
}
|
||||
42
script/release
Executable file
42
script/release
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Parse command line arguments
|
||||
minor=false
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--minor) minor=true; shift 1;;
|
||||
*) echo "Unknown parameter: $1"; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Get the latest release from GitHub
|
||||
latest_tag=$(gh release list --limit 1 --json tagName --jq '.[0].tagName')
|
||||
|
||||
# If there is no tag, exit the script
|
||||
if [ -z "$latest_tag" ]; then
|
||||
echo "No tags found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Latest tag: $latest_tag"
|
||||
|
||||
# Remove the 'v' prefix and split into major, minor, and patch numbers
|
||||
version_without_v=${latest_tag#v}
|
||||
IFS='.' read -ra VERSION <<< "$version_without_v"
|
||||
|
||||
if [ "$minor" = true ]; then
|
||||
# Increment the minor version and reset patch to 0
|
||||
minor_number=${VERSION[1]}
|
||||
let "minor_number++"
|
||||
new_version="${VERSION[0]}.$minor_number.0"
|
||||
else
|
||||
# Increment the patch version
|
||||
patch_number=${VERSION[2]}
|
||||
let "patch_number++"
|
||||
new_version="${VERSION[0]}.${VERSION[1]}.$patch_number"
|
||||
fi
|
||||
|
||||
echo "New version: $new_version"
|
||||
|
||||
gh workflow run publish.yml -f version="$new_version"
|
||||
|
||||
204
script/stats.ts
Executable file
204
script/stats.ts
Executable file
@@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
interface Asset {
|
||||
name: string
|
||||
download_count: number
|
||||
}
|
||||
|
||||
interface Release {
|
||||
tag_name: string
|
||||
name: string
|
||||
assets: Asset[]
|
||||
}
|
||||
|
||||
interface NpmDownloadsRange {
|
||||
start: string
|
||||
end: string
|
||||
package: string
|
||||
downloads: Array<{
|
||||
downloads: number
|
||||
day: string
|
||||
}>
|
||||
}
|
||||
|
||||
async function fetchNpmDownloads(packageName: string): Promise<number> {
|
||||
try {
|
||||
// Use a range from 2020 to current year + 5 years to ensure it works forever
|
||||
const currentYear = new Date().getFullYear()
|
||||
const endYear = currentYear + 5
|
||||
const response = await fetch(`https://api.npmjs.org/downloads/range/2020-01-01:${endYear}-12-31/${packageName}`)
|
||||
if (!response.ok) {
|
||||
console.warn(`Failed to fetch npm downloads for ${packageName}: ${response.status}`)
|
||||
return 0
|
||||
}
|
||||
const data: NpmDownloadsRange = await response.json()
|
||||
return data.downloads.reduce((total, day) => total + day.downloads, 0)
|
||||
} catch (error) {
|
||||
console.warn(`Error fetching npm downloads for ${packageName}:`, error)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchReleases(): Promise<Release[]> {
|
||||
const releases: Release[] = []
|
||||
let page = 1
|
||||
const per = 100
|
||||
|
||||
while (true) {
|
||||
const url = `https://api.github.com/repos/sst/opencode/releases?page=${page}&per_page=${per}`
|
||||
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) {
|
||||
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`)
|
||||
}
|
||||
|
||||
const batch: Release[] = await response.json()
|
||||
if (batch.length === 0) break
|
||||
|
||||
releases.push(...batch)
|
||||
console.log(`Fetched page ${page} with ${batch.length} releases`)
|
||||
|
||||
if (batch.length < per) break
|
||||
page++
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
}
|
||||
|
||||
return releases
|
||||
}
|
||||
|
||||
function calculate(releases: Release[]) {
|
||||
let total = 0
|
||||
const stats = []
|
||||
|
||||
for (const release of releases) {
|
||||
let downloads = 0
|
||||
const assets = []
|
||||
|
||||
for (const asset of release.assets) {
|
||||
downloads += asset.download_count
|
||||
assets.push({
|
||||
name: asset.name,
|
||||
downloads: asset.download_count,
|
||||
})
|
||||
}
|
||||
|
||||
total += downloads
|
||||
stats.push({
|
||||
tag: release.tag_name,
|
||||
name: release.name,
|
||||
downloads,
|
||||
assets,
|
||||
})
|
||||
}
|
||||
|
||||
return { total, stats }
|
||||
}
|
||||
|
||||
async function save(githubTotal: number, npmDownloads: number) {
|
||||
const file = "STATS.md"
|
||||
const date = new Date().toISOString().split("T")[0]
|
||||
const total = githubTotal + npmDownloads
|
||||
|
||||
let previousGithub = 0
|
||||
let previousNpm = 0
|
||||
let previousTotal = 0
|
||||
let content = ""
|
||||
|
||||
try {
|
||||
content = await Bun.file(file).text()
|
||||
const lines = content.trim().split("\n")
|
||||
|
||||
for (let i = lines.length - 1; i >= 0; i--) {
|
||||
const line = lines[i].trim()
|
||||
if (line.startsWith("|") && !line.includes("Date") && !line.includes("---")) {
|
||||
const match = line.match(
|
||||
/\|\s*[\d-]+\s*\|\s*([\d,]+)\s*(?:\([^)]*\))?\s*\|\s*([\d,]+)\s*(?:\([^)]*\))?\s*\|\s*([\d,]+)\s*(?:\([^)]*\))?\s*\|/,
|
||||
)
|
||||
if (match) {
|
||||
previousGithub = parseInt(match[1].replace(/,/g, ""))
|
||||
previousNpm = parseInt(match[2].replace(/,/g, ""))
|
||||
previousTotal = parseInt(match[3].replace(/,/g, ""))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
content =
|
||||
"# Download Stats\n\n| Date | GitHub Downloads | npm Downloads | Total |\n|------|------------------|---------------|-------|\n"
|
||||
}
|
||||
|
||||
const githubChange = githubTotal - previousGithub
|
||||
const npmChange = npmDownloads - previousNpm
|
||||
const totalChange = total - previousTotal
|
||||
|
||||
const githubChangeStr =
|
||||
githubChange > 0
|
||||
? ` (+${githubChange.toLocaleString()})`
|
||||
: githubChange < 0
|
||||
? ` (${githubChange.toLocaleString()})`
|
||||
: " (+0)"
|
||||
const npmChangeStr =
|
||||
npmChange > 0 ? ` (+${npmChange.toLocaleString()})` : npmChange < 0 ? ` (${npmChange.toLocaleString()})` : " (+0)"
|
||||
const totalChangeStr =
|
||||
totalChange > 0
|
||||
? ` (+${totalChange.toLocaleString()})`
|
||||
: totalChange < 0
|
||||
? ` (${totalChange.toLocaleString()})`
|
||||
: " (+0)"
|
||||
const line = `| ${date} | ${githubTotal.toLocaleString()}${githubChangeStr} | ${npmDownloads.toLocaleString()}${npmChangeStr} | ${total.toLocaleString()}${totalChangeStr} |\n`
|
||||
|
||||
if (!content.includes("# Download Stats")) {
|
||||
content =
|
||||
"# Download Stats\n\n| Date | GitHub Downloads | npm Downloads | Total |\n|------|------------------|---------------|-------|\n"
|
||||
}
|
||||
|
||||
await Bun.write(file, content + line)
|
||||
await Bun.spawn(["bunx", "prettier", "--write", file]).exited
|
||||
|
||||
console.log(
|
||||
`\nAppended stats to ${file}: GitHub ${githubTotal.toLocaleString()}${githubChangeStr}, npm ${npmDownloads.toLocaleString()}${npmChangeStr}, Total ${total.toLocaleString()}${totalChangeStr}`,
|
||||
)
|
||||
}
|
||||
|
||||
console.log("Fetching GitHub releases for sst/opencode...\n")
|
||||
|
||||
const releases = await fetchReleases()
|
||||
console.log(`\nFetched ${releases.length} releases total\n`)
|
||||
|
||||
const { total: githubTotal, stats } = calculate(releases)
|
||||
|
||||
console.log("Fetching npm all-time downloads for opencode-ai...\n")
|
||||
const npmDownloads = await fetchNpmDownloads("opencode-ai")
|
||||
console.log(`Fetched npm all-time downloads: ${npmDownloads.toLocaleString()}\n`)
|
||||
|
||||
await save(githubTotal, npmDownloads)
|
||||
|
||||
const totalDownloads = githubTotal + npmDownloads
|
||||
|
||||
console.log("=".repeat(60))
|
||||
console.log(`TOTAL DOWNLOADS: ${totalDownloads.toLocaleString()}`)
|
||||
console.log(` GitHub: ${githubTotal.toLocaleString()}`)
|
||||
console.log(` npm: ${npmDownloads.toLocaleString()}`)
|
||||
console.log("=".repeat(60))
|
||||
|
||||
console.log("\nDownloads by release:")
|
||||
console.log("-".repeat(60))
|
||||
|
||||
stats
|
||||
.sort((a, b) => b.downloads - a.downloads)
|
||||
.forEach((release) => {
|
||||
console.log(`${release.tag.padEnd(15)} ${release.downloads.toLocaleString().padStart(10)} downloads`)
|
||||
|
||||
if (release.assets.length > 1) {
|
||||
release.assets
|
||||
.sort((a, b) => b.downloads - a.downloads)
|
||||
.forEach((asset) => {
|
||||
console.log(` └─ ${asset.name.padEnd(25)} ${asset.downloads.toLocaleString().padStart(8)}`)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
console.log("-".repeat(60))
|
||||
console.log(`GitHub Total: ${githubTotal.toLocaleString()} downloads across ${releases.length} releases`)
|
||||
console.log(`npm Total: ${npmDownloads.toLocaleString()} downloads`)
|
||||
console.log(`Combined Total: ${totalDownloads.toLocaleString()} downloads`)
|
||||
Reference in New Issue
Block a user