name: Publish distribution branches on: push: branches: [staged] env: SOURCE_BRANCH: staged LEGACY_PUBLISHED_BRANCH: main MARKETPLACE_BRANCH: marketplace WEBSITE_DEPLOY_REF: main concurrency: group: publish-distribution-branches cancel-in-progress: true permissions: contents: write actions: write jobs: publish: runs-on: ubuntu-latest steps: - name: Checkout source branch uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: ref: ${{ env.SOURCE_BRANCH }} fetch-depth: 0 - name: Extract Node version from package.json id: node-version run: | NODE_VERSION=$(jq -r '.engines.node // "22"' package.json) echo "version=${NODE_VERSION}" >> "$GITHUB_OUTPUT" - name: Setup Node.js uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: ${{ steps.node-version.outputs.version }} - name: Install dependencies run: npm ci - name: Materialize plugin files run: node eng/materialize-plugins.mjs - name: Build generated files run: npm run build - name: Fix line endings run: bash eng/fix-line-endings.sh - name: Publish to distribution branches run: | set -euo pipefail git config user.name "github-actions[bot]" git config user.email "41898282+github-actions[bot]@users.noreply.github.com" snapshot_dir="$(mktemp -d)" main_worktree_dir="$(mktemp -d)" marketplace_worktree_dir="$(mktemp -d)" main_publish_ref="refs/heads/publish-${LEGACY_PUBLISHED_BRANCH}" marketplace_publish_ref="refs/heads/publish-${MARKETPLACE_BRANCH}" main_base_sha="" marketplace_base_sha="" cleanup() { git worktree remove --force "${main_worktree_dir}" 2>/dev/null || true git worktree remove --force "${marketplace_worktree_dir}" 2>/dev/null || true git update-ref -d "${main_publish_ref}" 2>/dev/null || true git update-ref -d "${marketplace_publish_ref}" 2>/dev/null || true rm -rf "${snapshot_dir}" } trap cleanup EXIT rsync -a --delete \ --exclude '.git' \ --exclude 'node_modules' \ ./ "${snapshot_dir}/" publish_branch() { local branch="$1" local worktree_dir="$2" local publish_ref="$3" local base_sha="" git fetch origin "${branch}" base_sha="$(git rev-parse "origin/${branch}")" git worktree add --force --detach "${worktree_dir}" "origin/${branch}" rsync -a --delete \ --exclude '.git' \ --exclude 'node_modules' \ "${snapshot_dir}/" "${worktree_dir}/" ( cd "${worktree_dir}" git add -A find plugins -mindepth 2 -maxdepth 2 -type d \( -name agents -o -name skills \) -exec git add -f -- '{}' + git commit -m "chore: publish from ${SOURCE_BRANCH}" --allow-empty git update-ref "${publish_ref}" HEAD ) if [[ "${branch}" == "${LEGACY_PUBLISHED_BRANCH}" ]]; then main_base_sha="${base_sha}" elif [[ "${branch}" == "${MARKETPLACE_BRANCH}" ]]; then marketplace_base_sha="${base_sha}" fi } publish_branch "${LEGACY_PUBLISHED_BRANCH}" "${main_worktree_dir}" "${main_publish_ref}" publish_branch "${MARKETPLACE_BRANCH}" "${marketplace_worktree_dir}" "${marketplace_publish_ref}" git fetch origin "${LEGACY_PUBLISHED_BRANCH}" "${MARKETPLACE_BRANCH}" current_main_tip="$(git rev-parse "origin/${LEGACY_PUBLISHED_BRANCH}")" current_marketplace_tip="$(git rev-parse "origin/${MARKETPLACE_BRANCH}")" drift_detected=false if [[ "${current_main_tip}" != "${main_base_sha}" ]]; then echo "Remote branch tip changed: ${LEGACY_PUBLISHED_BRANCH} expected ${main_base_sha}, got ${current_main_tip}" drift_detected=true fi if [[ "${current_marketplace_tip}" != "${marketplace_base_sha}" ]]; then echo "Remote branch tip changed: ${MARKETPLACE_BRANCH} expected ${marketplace_base_sha}, got ${current_marketplace_tip}" drift_detected=true fi if [[ "${drift_detected}" == true ]]; then echo "Concurrent branch update detected during publish. Please rerun the publish workflow." exit 1 fi git push origin --atomic \ "${main_publish_ref}:${LEGACY_PUBLISHED_BRANCH}" \ "${marketplace_publish_ref}:${MARKETPLACE_BRANCH}" - name: Dispatch website deployment run: gh workflow run deploy-website.yml --ref "${WEBSITE_DEPLOY_REF}" env: GH_TOKEN: ${{ github.token }}