diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..88353f7 --- /dev/null +++ b/.github/workflows/publish.yml @@ -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 \ No newline at end of file diff --git a/recipes/.gitkeep b/recipes/.gitkeep new file mode 100644 index 0000000..e69de29