Skip to content
Draft
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
42 changes: 21 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,38 +93,38 @@ jobs:
uses: tj-actions/changed-files@v45
with:
files: |
plugins/*/src/**
plugins/*/test/**
plugins/*/*.test.ts
plugins/*/*.test.tsx
plugins/*/vitest.config.ts
plugins/*/test-setup.ts
{plugins,packages}/*/src/**
{plugins,packages}/*/test/**
{plugins,packages}/*/*.test.ts
{plugins,packages}/*/*.test.tsx
{plugins,packages}/*/vitest.config.ts
{plugins,packages}/*/test-setup.ts

- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
run: yarn

- name: Get changed plugins
- name: Get changed workspaces
if: steps.changed-files.outputs.any_changed == 'true'
id: changed-plugins
id: changed-workspaces
run: |
# Extract unique plugin names from changed files
PLUGINS=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | \
grep -E '^plugins/[^/]+/' | \
cut -d'/' -f2 | \
# Extract unique workspace paths from changed files
WORKSPACES=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | \
grep -oE '(plugins|packages)/[^/]+' | \
sort -u | \
tr '\n' ' ')
echo "plugins=$PLUGINS" >> $GITHUB_OUTPUT
echo "Changed plugins: $PLUGINS"
echo "workspaces=$WORKSPACES" >> $GITHUB_OUTPUT
echo "Changed workspaces: $WORKSPACES"

- name: Run tests for changed plugins
if: steps.changed-files.outputs.any_changed == 'true' && steps.changed-plugins.outputs.plugins != ''
- name: Run tests for changed workspaces
if: steps.changed-files.outputs.any_changed == 'true' && steps.changed-workspaces.outputs.workspaces != ''
run: |
for plugin in ${{ steps.changed-plugins.outputs.plugins }}; do
echo "Checking tests for plugin: $plugin"
if [ -f "plugins/$plugin/package.json" ] && grep -q '"check-vitest"' "plugins/$plugin/package.json"; then
yarn workspace $plugin check-vitest
for workspace in ${{ steps.changed-workspaces.outputs.workspaces }}; do
echo "Checking tests for workspace: $workspace"
if [ -f "$workspace/package.json" ] && grep -q '"check-vitest"' "$workspace/package.json"; then
name=$(jq -r '.name' "$workspace/package.json")
yarn workspace "$name" check-vitest
else
echo "No check-vitest script found for $plugin, skipping..."
echo "No check-vitest script found for $workspace, skipping..."
fi
done
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@
"g:dev": "cd $INIT_CWD && run g:vite",
"g:preview": "cd $INIT_CWD && run g:vite preview",
"g:vite": "cd $INIT_CWD && NODE_OPTIONS='--no-warnings=ExperimentalWarning' vite --config ${VITE_CONFIG_PATH:-$PROJECT_CWD/packages/vite-config/src/index.ts}",
"g:pack": "cd $INIT_CWD && framer-plugin-tools pack",
"preview": "turbo run preview --concurrency=40"
},
"devDependencies": {
"@biomejs/biome": "^2.2.4",
"@framer/eslint-config": "workspace:*",
"@framer/vite-config": "workspace:*",
"eslint": "^9.35.0",
"framer-plugin-tools": "workspace:*",
"jiti": "^2.5.1",
"turbo": "^2.5.6",
"typescript": "^5.9.2",
Expand Down
8 changes: 8 additions & 0 deletions packages/plugin-tools/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Yarn v2 with Zero Installs (https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored)
.yarn/*
!.yarn/cache
!.yarn/releases
!.yarn/patches
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
10 changes: 10 additions & 0 deletions packages/plugin-tools/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: build publish publish-alpha

build:
yarn build

publish:
yarn npm publish

publish-alpha:
yarn npm publish --tag alpha
42 changes: 42 additions & 0 deletions packages/plugin-tools/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# framer-plugin-tools

CLI tools for building and packaging Framer plugins.

## Installation

```bash
npm install -g framer-plugin-tools
```

Or use directly with npx:

```bash
npx framer-plugin-tools pack
```

## Usage

### `pack`

Builds your plugin and creates a `plugin.zip` file ready for submission to the Framer Marketplace.

```bash
framer-plugin-tools pack
```

This command will:

1. Run `npm run build` in the current directory
2. Create a `plugin.zip` from the `dist/` folder

For custom options (e.g., custom build command, different output directory), run:

```bash
framer-plugin-tools pack --help
```


## Submitting Your Plugin

After running `pack`, submit your plugin at:
https://www.framer.com/marketplace/dashboard/plugins/
49 changes: 49 additions & 0 deletions packages/plugin-tools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "framer-plugin-tools",
"version": "1.1.0",
"description": "CLI Tools for Framer Plugins",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"bin": "dist/cli.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
}
},
"files": [
"dist"
],
"repository": {
"type": "git",
"url": "git+https://github.com/framer/plugins.git",
"directory": "packages/plugin-tools"
},
"scripts": {
"build": "tsup",
"check-vitest": "run g:check-vitest",
"check-biome": "run g:check-biome",
"check-eslint": "run g:check-eslint",
"check-typescript": "run g:check-typescript",
"prepublishOnly": "yarn run build"
},
"author": "",
"license": "MIT",
"engines": {
"node": ">=22"
},
"dependencies": {
"@commander-js/extra-typings": "^13.1.0",
"adm-zip": "^0.5.16",
"commander": "^13.1.0"
},
"devDependencies": {
"@types/adm-zip": "^0.5.7",
"@types/node": "^22.0.0",
"tsup": "^8.0.0",
"typescript": "^5.9.2",
"vitest": "^3.2.4"
}
}
43 changes: 43 additions & 0 deletions packages/plugin-tools/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import path from "node:path"
import { program } from "@commander-js/extra-typings"
import { runPluginBuildScript, zipPluginDistribution } from "./lib"

const defaultDistDir = "dist"
const defaultOutputFilename = "plugin.zip"
const defaultCWD = process.cwd()

program.name("framer-plugin").description("CLI tools for Framer Plugins").version("1.1.0")

program
.command("pack")
.alias("prepare") // Backwards compatibility but was never documented
.description("Build and package your plugin into a zip file")
// Uppercase -C matches familiar git shorthands
.option("-C, --cwd <dir>", "plugin project directory", defaultCWD)
.option("-d, --dist-dir <dir>", "output directory for the build", defaultDistDir)
.option("-b, --build-command <cmd>", "custom build command (e.g., 'npm run build:prod')")
.option("--prebuilt", "skip the build step and only create the zip")
.option("-o, --output <filename>", "output zip filename", defaultOutputFilename)
.action(async options => {
if (!options.prebuilt) {
console.log("Building your Plugin…")
await runPluginBuildScript(options.cwd, options.buildCommand)
}

console.log(`Creating ${options.output} file…`)

const zipFilePath = zipPluginDistribution({
cwd: options.cwd,
distPath: options.distDir,
zipFileName: options.output,
})

const fileName = path.basename(zipFilePath)
const dirName = path.dirname(zipFilePath)

console.log(
`\n⚡️ ${fileName} file has been created in ${dirName} \n Submit your Plugin on the Framer Marketplace: https://www.framer.com/marketplace/dashboard/plugins/`
)
})

program.parse(process.argv)
1 change: 1 addition & 0 deletions packages/plugin-tools/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { runPluginBuildScript, zipPluginDistribution } from "./lib"
Loading
Loading