chore: setup CI scripts (#6)
* wip: workflows * wip: fix up issues in ci scripts and fix frontend lint errors * wip: fix backend lints * remove unused deps * wip: build frontend in test.yml * wip: attempt to improve Rust caching * wip: testing release * wip: linear release flow * wip: check against both package.json versions * wip: spurious attempt to get Rust caching * wip: more cache * merge release and publish jobs; add more caching to release flow * decouple github releases and npm publishing * update pack flow --------- Co-authored-by: couscous <couscous@runner.com>
This commit is contained in:
committed by
GitHub
parent
b25f81504a
commit
340b094c75
136
.github/workflows/pre-release.yml
vendored
Normal file
136
.github/workflows/pre-release.yml
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
# To pre-release:
|
||||
# ```
|
||||
# git tag -a v0.1.0 -m "Release 0.1.0"
|
||||
# git push origin v0.1.0
|
||||
# ```
|
||||
|
||||
name: Create GitHub Pre-Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
|
||||
concurrency:
|
||||
group: release
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
NODE_VERSION: 22
|
||||
PNPM_VERSION: 10.8.1
|
||||
TAG_REGEX: '^v[0-9]+\.[0-9]+\.[0-9]+$'
|
||||
|
||||
jobs:
|
||||
tag-check:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref_type == 'tag'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Validate tag matches package.json version
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "::group::Tag validation"
|
||||
|
||||
# 1. Must be a tag and match the regex
|
||||
[[ "${GITHUB_REF_TYPE}" == "tag" ]] \
|
||||
|| { echo "❌ Not a tag push"; exit 1; }
|
||||
[[ "${GITHUB_REF_NAME}" =~ ${TAG_REGEX} ]] \
|
||||
|| { echo "❌ Tag '${GITHUB_REF_NAME}' != ${TAG_REGEX}"; exit 1; }
|
||||
|
||||
# 2. Extract versions
|
||||
tag_ver="${GITHUB_REF_NAME#v}"
|
||||
package_ver="$(node -p "require('./package.json').version")"
|
||||
cli_package_ver="$(node -p "require('./npx-cli/package.json').version")"
|
||||
|
||||
# 3. Compare
|
||||
[[ "${tag_ver}" == "${package_ver}" ]] \
|
||||
|| { echo "❌ Tag ${tag_ver} ≠ package.json ${package_ver}"; exit 1; }
|
||||
|
||||
# 4. Compare tag with npx-cli package.json
|
||||
[[ "${tag_ver}" == "${cli_package_ver}" ]] \
|
||||
|| { echo "❌ Tag ${tag_ver} ≠ npx-cli package.json ${cli_package_ver}"; exit 1; }
|
||||
|
||||
echo "✅ Tag and package.json agree (${tag_ver})"
|
||||
echo "::endgroup::"
|
||||
|
||||
create-prerelease:
|
||||
needs: tag-check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Lint frontend
|
||||
run: cd frontend && npm run lint
|
||||
|
||||
- name: Type check frontend
|
||||
run: cd frontend && npx tsc --noEmit
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly-2025-05-18
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Build frontend
|
||||
run: npm run frontend:build
|
||||
|
||||
- name: Cache Rust dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
env:
|
||||
RUST_CACHE_DEBUG: true
|
||||
with:
|
||||
workspaces: "backend"
|
||||
|
||||
- name: Checks
|
||||
run: |
|
||||
cargo fmt --all -- --check
|
||||
cargo test --workspace
|
||||
cargo clippy --all --all-targets --all-features -- -D warnings
|
||||
|
||||
- name: Build backend
|
||||
run: cargo build --release --manifest-path backend/Cargo.toml
|
||||
|
||||
- name: Get version from tag
|
||||
id: get-version
|
||||
run: echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Zip backend
|
||||
run: |
|
||||
mkdir vibe-kanban-${{ github.ref_name }}
|
||||
mv target/release/vibe-kanban vibe-kanban-${{ github.ref_name }}
|
||||
mv frontend/dist vibe-kanban-${{ github.ref_name }}
|
||||
zip -r vibe-kanban-${{ github.ref_name }}.zip vibe-kanban-${{ github.ref_name }}
|
||||
|
||||
- name: Code sign
|
||||
run: echo "pass"
|
||||
|
||||
- name: Pack
|
||||
run: |
|
||||
mkdir -p npx-cli/dist/linux-x64
|
||||
mv vibe-kanban-${{ github.ref_name }}.zip npx-cli/dist/linux-x64
|
||||
cd npx-cli
|
||||
npm pack
|
||||
|
||||
- name: Create GitHub Pre-Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: Pre-release ${{ github.ref_name }}
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
files: |
|
||||
vibe-kanban-${{ github.ref_name }}.zip
|
||||
npx-cli/vibe-kanban-*.tgz
|
||||
114
.github/workflows/publish.yml
vendored
Normal file
114
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
|
||||
concurrency:
|
||||
group: publish
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
NODE_VERSION: 22
|
||||
PNPM_VERSION: 10.8.1
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
# Only run if this was converted from a pre-release
|
||||
if: github.event.release.prerelease == false
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.event.release.tag_name }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Configure npm authentication
|
||||
run: |
|
||||
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
|
||||
|
||||
- name: Download release assets
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Get the release assets
|
||||
const release = await github.rest.repos.getRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: context.payload.release.id
|
||||
});
|
||||
|
||||
// Find the .tgz file
|
||||
const tgzAsset = release.data.assets.find(asset => asset.name.endsWith('.tgz'));
|
||||
|
||||
if (!tgzAsset) {
|
||||
core.setFailed('No .tgz file found in release assets');
|
||||
return;
|
||||
}
|
||||
|
||||
// Download the asset
|
||||
const response = await github.rest.repos.getReleaseAsset({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
asset_id: tgzAsset.id,
|
||||
headers: {
|
||||
Accept: 'application/octet-stream'
|
||||
}
|
||||
});
|
||||
|
||||
// Save to npx-cli directory
|
||||
const filePath = path.join('npx-cli', tgzAsset.name);
|
||||
fs.writeFileSync(filePath, Buffer.from(response.data));
|
||||
|
||||
console.log(`Downloaded ${tgzAsset.name} to ${filePath}`);
|
||||
|
||||
// Set output for next step
|
||||
core.setOutput('package-file', filePath);
|
||||
core.setOutput('package-name', tgzAsset.name);
|
||||
|
||||
- name: Verify package integrity
|
||||
id: verify
|
||||
run: |
|
||||
cd npx-cli
|
||||
|
||||
# List files to confirm download
|
||||
ls -la *.tgz
|
||||
|
||||
# Verify the package can be read
|
||||
npm pack --dry-run || echo "Note: This is expected to show differences since we're using the pre-built package"
|
||||
|
||||
# Extract package name from the downloaded file
|
||||
PACKAGE_FILE=$(ls *.tgz | head -n1)
|
||||
echo "package-file=$PACKAGE_FILE" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
cd npx-cli
|
||||
|
||||
# Publish the exact same package that was tested
|
||||
PACKAGE_FILE="${{ steps.verify.outputs.package-file }}"
|
||||
|
||||
echo "Publishing $PACKAGE_FILE to npm..."
|
||||
npm publish "$PACKAGE_FILE"
|
||||
|
||||
echo "✅ Successfully published to npm!"
|
||||
|
||||
- name: Update release description
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.repos.updateRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: context.payload.release.id,
|
||||
body: context.payload.release.body + '\n\n✅ **Published to npm registry**'
|
||||
});
|
||||
57
.github/workflows/test.yml
vendored
Normal file
57
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
NODE_VERSION: 22
|
||||
PNPM_VERSION: 10.8.1
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Lint frontend
|
||||
run: cd frontend && npm run lint
|
||||
|
||||
- name: Format check frontend
|
||||
run: cd frontend && npm run format:check
|
||||
|
||||
- name: Type check frontend
|
||||
run: cd frontend && npx tsc --noEmit
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly-2025-05-18
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Build frontend
|
||||
run: cd frontend && npm run build
|
||||
|
||||
- name: Cache Rust dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
env:
|
||||
RUST_CACHE_DEBUG: true
|
||||
with:
|
||||
workspaces: "backend"
|
||||
|
||||
- name: Checks
|
||||
run: |
|
||||
cargo fmt --all -- --check
|
||||
cargo test --workspace
|
||||
cargo clippy --all --all-targets --all-features -- -D warnings
|
||||
Reference in New Issue
Block a user