Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json

# For more information see: https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/running-variations-of-jobs-in-a-workflow

name: Publish Codemod

on:
push:
tags:
- "v*@*" # eg: v1.0.0@codemod-name
workflow_dispatch:
inputs:
tag:
description: "Tag to publish (format: v1.0.0@codemod-name)"
required: true
type: string

jobs:
validate-and-publish:
name: Validate and Publish Codemod
environment: publish
runs-on: ubuntu-latest

outputs:
version: ${{ steps.parse-tag.outputs.version }}
codemod-name: ${{ steps.parse-tag.outputs.codemod-name }}
codemod-path: ${{ steps.parse-tag.outputs.codemod-path }}

steps:
- name: Checkout repository
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
fetch-depth: 0

- name: Parse tag and extract metadata
id: parse-tag
env:
EVENT_NAME: ${{ github.event_name }}
INPUT_TAG: ${{ github.event.inputs.tag }}
GITHUB_REF: ${{ github.ref }}
run: |
# Determine the tag based on trigger type
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
TAG="$INPUT_TAG"
echo "Using manually provided tag: $TAG"
else
TAG="${GITHUB_REF#refs/tags/}"
echo "Using pushed tag: $TAG"
fi

# Validate tag format
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+@[a-zA-Z0-9_-]+$ ]]; then
echo "❌ Invalid tag format: $TAG"
echo "Expected format: v1.0.0@codemod-name"
exit 1
fi

# Extract components
VERSION="${TAG%@*}" # Everything before @
VERSION="${VERSION#v}" # Remove v prefix
CODEMOD_NAME="${TAG#*@}" # Everything after @
CODEMOD_PATH="recipes/$CODEMOD_NAME"

# Set outputs
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "codemod-name=$CODEMOD_NAME" >> $GITHUB_OUTPUT
echo "codemod-path=$CODEMOD_PATH" >> $GITHUB_OUTPUT

- name: Verify codemod directory
env:
CODEMOD_PATH: ${{ steps.parse-tag.outputs.codemod-path }}
run: |
if [[ ! -d "$CODEMOD_PATH" ]]; then
echo "❌ Codemod directory not found: $CODEMOD_PATH"
echo "Available directories in recipes/:"
ls -lah recipes/ || echo "No recipes directory found"
exit 1
fi

echo "✓ Found codemod directory: $CODEMOD_PATH"
echo "Directory contents:"
ls -lah "$CODEMOD_PATH"

- name: Setup Node.js environment
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
cache: npm
cache-dependency-path: package-lock.json

# We don't use dev dependencies
# But we need npm to put local workspace in `node_modules`
# so codemod can bundle workspaces in the codemod tarball correctly
- name: Install project dependencies
run: npm ci

# Run test before login to not waste time if it fails
- name: Run codemod Tests
working-directory: ${{ steps.parse-tag.outputs.codemod-path }}
run: node --run test

- name: Authenticate with Codemod registry
env:
CODEMOD_TOKEN: ${{ secrets.CODEMOD_TOKEN }}
run: npx codemod login --api-key "$CODEMOD_TOKEN"

- name: Publish codemod
working-directory: ${{ steps.parse-tag.outputs.codemod-path }}
run: npx codemod publish

- name: Create release summary
env:
CODEMOD_NAME: ${{ steps.parse-tag.outputs.codemod-name }}
VERSION: ${{ steps.parse-tag.outputs.version }}
TAG: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.tag || github.ref_name }}
TRIGGER: ${{ github.event_name == 'workflow_dispatch' && 'Manual' || 'Tag Push' }}
ACTOR: ${{ github.triggering_actor }}
run: |
cat >> $GITHUB_STEP_SUMMARY << EOF
# 🚀 Codemod Publication Summary

**Codemod:** \`$CODEMOD_NAME\`
**Version:** \`$VERSION\`
**Tag:** \`$TAG\`
**Trigger:** $TRIGGER by $ACTOR

✅ Codemod has been successfully published to the registry!
EOF
Empty file added recipes/.gitkeep
Empty file.