chore: import upstream snapshot with attribution
docmd CI verification / verify (push) Failing after 0s
docmd CI verification / verify (push) Failing after 0s
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
name: docmd CI verification
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Build packages
|
||||
run: pnpm -r run build
|
||||
|
||||
- name: Run verification
|
||||
run: pnpm verify --skip-setup
|
||||
|
||||
- name: Run Linting
|
||||
run: pnpm lint
|
||||
@@ -0,0 +1,219 @@
|
||||
# --------------------------------------------------------------------
|
||||
# docmd : the minimalist, zero-config documentation generator.
|
||||
#
|
||||
# @package @docmd/core (and ecosystem)
|
||||
# @website https://docmd.io
|
||||
# @repository https://github.com/docmd-io/docmd
|
||||
# @license MIT
|
||||
# @copyright Copyright (c) 2025-present docmd.io
|
||||
#
|
||||
# [docmd-source] - Please do not remove this header.
|
||||
# --------------------------------------------------------------------
|
||||
#
|
||||
# GitHub Actions workflow for building and publishing Docker images
|
||||
# Uses OIDC (OpenID Connect) for passwordless authentication to GHCR
|
||||
#
|
||||
# Triggers:
|
||||
# - Release published on GitHub
|
||||
# - Manual workflow dispatch
|
||||
# - Push to main (for testing)
|
||||
#
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
push_image:
|
||||
description: 'Push image to registry'
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
version:
|
||||
description: 'Version tag (e.g., X.Y.Z)'
|
||||
required: false
|
||||
type: string
|
||||
tag_latest:
|
||||
description: 'Also tag this build as :latest (use only for stable releases)'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write # Required for OIDC
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
|
||||
jobs:
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build and push Docker image
|
||||
# ---------------------------------------------------------------------------
|
||||
build:
|
||||
name: Build Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.meta.outputs.version }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Set up Docker Buildx for multi-platform builds
|
||||
# -------------------------------------------------------------------------
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Login to GitHub Container Registry using OIDC
|
||||
# The id-token: write permission enables passwordless authentication
|
||||
# -------------------------------------------------------------------------
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Extract metadata for Docker
|
||||
# -------------------------------------------------------------------------
|
||||
- name: Extract Docker metadata
|
||||
# Skip on plain branch pushes (the "for testing" trigger) — the
|
||||
# build below is local-only (push: is gated to release / manual),
|
||||
# so no tags are needed and the action's tag rules don't apply.
|
||||
if: github.event_name != 'push' || startsWith(github.ref, 'refs/tags/')
|
||||
id: meta
|
||||
uses: docker/metadata-action@v6
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ github.repository }}
|
||||
# Two and only two tags are ever produced for any single image:
|
||||
# - The version (e.g. X.Y.Z, v-prefix stripped)
|
||||
# - The floating `:latest` alias
|
||||
# `:latest` is only ever applied to released versions. A branch
|
||||
# build or unreleased commit can never be pulled as `:latest`.
|
||||
# flavor=latest=false disables the action's auto-latest so the
|
||||
# only source of `:latest` is the explicit rule below.
|
||||
flavor: |
|
||||
latest=false
|
||||
tags: |
|
||||
# Version: ref on tag push and release events (strips 'v' prefix)
|
||||
type=ref,event=tag
|
||||
# :latest — only on release events
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||
# Manual dispatch: use provided version + optional :latest
|
||||
type=raw,value=${{ inputs.version }},enable=${{ github.event_name == 'workflow_dispatch' && inputs.version != '' }}
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'workflow_dispatch' && inputs.tag_latest }}
|
||||
labels: |
|
||||
org.opencontainers.image.title=docmd
|
||||
org.opencontainers.image.description=The minimalist, zero-config documentation generator
|
||||
org.opencontainers.image.vendor=docmd.io
|
||||
org.opencontainers.image.licenses=MIT
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Build and push Docker image
|
||||
# Multi-platform: linux/amd64, linux/arm64
|
||||
# -------------------------------------------------------------------------
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.push_image) }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
provenance: true
|
||||
sbom: true
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Output build info
|
||||
# -------------------------------------------------------------------------
|
||||
- name: Output image info
|
||||
run: |
|
||||
echo "## Docker Image Published! :whale:" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Image Details" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Registry | \`${{ env.REGISTRY }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Image | \`${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.meta.outputs.version }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Version | \`${{ steps.meta.outputs.version }}\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Platforms | \`linux/amd64, linux/arm64\` |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Usage" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```bash' >> $GITHUB_STEP_SUMMARY
|
||||
echo "# Pull the image" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker pull ${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.meta.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "# Run development server" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker run -v \$(pwd)/docs:/docs -p 3000:3000 ${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.meta.outputs.version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "# Build static site" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker run -v \$(pwd)/docs:/docs -v \$(pwd)/site:/site ${{ env.REGISTRY }}/${{ github.repository }}:${{ steps.meta.outputs.version }} build" >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Test the Docker image (optional but recommended)
|
||||
# ---------------------------------------------------------------------------
|
||||
test:
|
||||
name: Test Docker Image
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.push_image)
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Pull image
|
||||
run: docker pull ${{ env.REGISTRY }}/${{ github.repository }}:${{ needs.build.outputs.version }}
|
||||
|
||||
- name: Test build command
|
||||
run: |
|
||||
# Create test directory with proper permissions for container user (UID 1001)
|
||||
mkdir -p /tmp/docmd-test
|
||||
sudo chown -R 1001:1001 /tmp/docmd-test
|
||||
|
||||
# Simulate exactly what a new user does: init a project then build it
|
||||
docker run --rm \
|
||||
-v /tmp/docmd-test:/workspace \
|
||||
--workdir /workspace \
|
||||
--entrypoint sh \
|
||||
${{ env.REGISTRY }}/${{ github.repository }}:${{ needs.build.outputs.version }} \
|
||||
-c "cp -r /template/. /workspace/ && docmd build"
|
||||
|
||||
- name: Verify build output
|
||||
run: |
|
||||
if [ -f "/tmp/docmd-test/site/index.html" ]; then
|
||||
echo "✅ Build successful - site/index.html exists"
|
||||
echo "📊 Site size: $(du -sh /tmp/docmd-test/site | cut -f1)"
|
||||
else
|
||||
echo "❌ Build failed - site/index.html not found"
|
||||
ls -la /tmp/docmd-test/
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,180 @@
|
||||
name: Release docmd to NPM
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
packages: write
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Job 1: Build Rust native binaries (matrix, one runner per platform)
|
||||
#
|
||||
# Each runner compiles the napi-rs addon for its target, then uploads the
|
||||
# resulting .node file as a workflow artifact. The publish job downloads
|
||||
# all artifacts and places them in rust-binaries/bin/ before publishing.
|
||||
# ---------------------------------------------------------------------------
|
||||
jobs:
|
||||
build-native:
|
||||
name: Build native (${{ matrix.target }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: macos-latest # Apple Silicon runner (M-series)
|
||||
target: aarch64-apple-darwin
|
||||
binary: docmd-engine-darwin-arm64.node
|
||||
lib: libdocmd_engine.dylib
|
||||
|
||||
- os: macos-latest # Cross-compile Intel binary on ARM64 runner (Faster)
|
||||
target: x86_64-apple-darwin
|
||||
binary: docmd-engine-darwin-x64.node
|
||||
lib: libdocmd_engine.dylib
|
||||
|
||||
- os: ubuntu-latest # Cross-compile Linux x64 binary on ARM64 runner (Faster)
|
||||
target: x86_64-unknown-linux-gnu
|
||||
binary: docmd-engine-linux-x64.node
|
||||
lib: libdocmd_engine.so
|
||||
|
||||
- os: ubuntu-24.04-arm # GitHub-hosted ARM64 Linux runner
|
||||
target: aarch64-unknown-linux-gnu
|
||||
binary: docmd-engine-linux-arm64.node
|
||||
lib: libdocmd_engine.so
|
||||
|
||||
- os: windows-latest # Cross-compile Windows x64 binary on ARM64 runner (Faster)
|
||||
target: x86_64-pc-windows-msvc
|
||||
binary: docmd-engine-win32-x64.node
|
||||
lib: docmd_engine.dll
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
rustup toolchain install stable --profile minimal --target ${{ matrix.target }}
|
||||
rustup default stable
|
||||
|
||||
- name: Cache Rust build
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: packages/engines/rust-binaries/native
|
||||
|
||||
- name: Debug cargo environment
|
||||
run: |
|
||||
echo "PATH: $PATH"
|
||||
which cargo
|
||||
cargo --version
|
||||
rustup show
|
||||
|
||||
- name: Build native addon
|
||||
working-directory: packages/engines/rust-binaries/native
|
||||
run: cargo build --release --target ${{ matrix.target }}
|
||||
|
||||
# Copy the built library to bin/ with the correct name
|
||||
- name: Collect binary (Unix)
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
mkdir -p packages/engines/rust-binaries/bin
|
||||
cp packages/engines/rust-binaries/native/target/${{ matrix.target }}/release/${{ matrix.lib }} \
|
||||
packages/engines/rust-binaries/bin/${{ matrix.binary }}
|
||||
|
||||
- name: Collect binary (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
New-Item -ItemType Directory -Force -Path packages/engines/rust-binaries/bin
|
||||
Copy-Item "packages/engines/rust-binaries/native/target/${{ matrix.target }}/release/${{ matrix.lib }}" `
|
||||
"packages/engines/rust-binaries/bin/${{ matrix.binary }}"
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: native-${{ matrix.target }}
|
||||
path: packages/engines/rust-binaries/bin/${{ matrix.binary }}
|
||||
if-no-files-found: error
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Job 2: Publish all packages to npm
|
||||
#
|
||||
# Runs after all matrix builds succeed. Downloads every .node artifact into
|
||||
# rust-binaries/bin/ so the package contains the binaries when npm publish runs.
|
||||
# ---------------------------------------------------------------------------
|
||||
publish:
|
||||
name: Publish to npm
|
||||
needs: build-native
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: '24'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Upgrade npm (required for OIDC provenance)
|
||||
run: npm install -g npm@11.12.1
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile --ignore-scripts
|
||||
|
||||
# Download all .node binaries built by the matrix into rust-binaries/bin/
|
||||
- name: Download native binaries
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
pattern: native-*
|
||||
path: packages/engines/rust-binaries/bin
|
||||
merge-multiple: true
|
||||
|
||||
- name: Verify binaries
|
||||
run: ls -lh packages/engines/rust-binaries/bin/
|
||||
|
||||
# Build TypeScript for all packages
|
||||
- name: Build packages
|
||||
run: pnpm -r run build
|
||||
|
||||
- name: Run verification
|
||||
run: pnpm verify --skip-setup
|
||||
|
||||
- name: Copy LICENSE into each package
|
||||
run: |
|
||||
find packages -mindepth 1 -maxdepth 4 -name "package.json" \
|
||||
-not -path "*/node_modules/*" \
|
||||
-exec dirname {} \; | xargs -I % cp LICENSE %
|
||||
|
||||
- name: Resolve workspace dependencies
|
||||
run: node tools/resolve-ws-deps.js
|
||||
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
for dir in packages/* packages/legacy/* packages/plugins/* packages/engines/* packages/templates/*; do
|
||||
if [ -f "$dir/package.json" ]; then
|
||||
# Skip private packages
|
||||
if grep -q '"private": true' "$dir/package.json"; then
|
||||
echo "::notice::Skipping $dir: private package"
|
||||
continue
|
||||
fi
|
||||
echo "Publishing $dir..."
|
||||
exit_code=0
|
||||
publish_output=$(npm publish "./$dir" --access public --provenance 2>&1) || exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
if echo "$publish_output" | grep -q 'previously published versions\|EPRIVATE'; then
|
||||
echo "::notice::Skipping $dir: Already published or private."
|
||||
else
|
||||
echo "::error::Failed to publish $dir"
|
||||
echo "$publish_output"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
Reference in New Issue
Block a user