grunt-cep

A Grunt plugin that helps debugging and packaging HTML5-based extensions for Adobe Creative Cloud applications.

Usage no npm install needed!

<script type="module">
  import gruntCep from 'https://cdn.skypack.dev/grunt-cep';
</script>

README

grunt-cep

A Grunt plugin that helps debugging and packaging HTML5-based extensions for Adobe Creative Cloud applications.

By using this task you can debug and package HTML5-based extensions for Adobe® Creative Cloud® products directly from Grunt, in a totally automated manner and without the Adobe Extension Builder plugin.

The tool can automatically generate self-signed certificates for extension packaging and automates some error-prone tasks such as bundle and extension manifest files creation. It supports hybrid extensions and lets you create different builds of an extension bundle based on targeted Adobe products.

It is based on the csxs command line tool by Creative Market.

Changelog

See changelog.md.

Getting Started

Install the plugin:

npm install grunt-cep --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile as usual:

grunt.loadNpmTasks('grunt-cep');

Project Boilerplate

You can use the grunt-init-cep template to easily get started. The template tool will install all the required files automatically and provide you with a basic extension boilerplate, already configured to run inside the chosen target applications.

Please refer to the grunt-init-cep documentation for installation and usage instruction.

Advanced Setup

Bundle icon, manifest, MXI and update.xml files provided by the template can also be found in the res/bundle folder located inside the plugin installation folder. If you prefer, you can manually copy these files instead of using the grunt-init-cep template.

grunt-cep is setup to use these files by default, so just copy the res/bundle folder to the root of your project (that is, the same folder of your Gruntfile.js) and you should be good to go.

Custom Manifest, XML and MXI Files

XML and MXI template files are populated at build time using configuration properties. For most extensions the provided templates should work just fine, but for complex extensions it might be necessary to make changes to these files or even provide custom ones.

Note that grunt-cep makes no assumptions about and does no validation on extension files content, so be sure to provide valid files and to modify extension configuration accordingly.

The cep Task

You may run the task with this command:

grunt cep

Options

grunt-cep has several options that you can customize to fit your needs. To avoid cluttering your Gruntfile.js it is more advisable to keep the options in an external Javascript or JSON file for easier editing and import them at run-time using either:

require('cep-config.js');

or:

grunt.file.readJSON('cep-config.json');

Options defined in the external file can be overwritten in child tasks as needed (see the example below). Default values and a more in-depth description for all the properties below can be found in the /options/defaults.js file in the plugin installation folder.

options

These properties define base task options.

profile String

The active build profile. Valid properties include:

  • debug: builds the extension in debug mode, that includes files such as .debug for remote extension debugging.

    Please note: when building using the debug profile a .debug suffix is automatically added to the name and id of the extension.

  • launch: builds the extension in debug mode as above, but also installs it into the host application extensions folder and starts the host application.
  • package: compiles all the extension builds (see below) in release mode and creates the final .ZXP package ready for distribution.
staging String Path of the temporary folder that the plugin should use when building and packaging the extension. The results of the build can be found in this folder. It should be excluded from source control.
source String

Path to the input folder containing extension files such as HTML and ExtendScript files that the plugin should compile for debugging and packaging.

This can either be a folder containing raw source files or the result of the automated build process when using other Grunt plugins such as grunt-contrib-requirejs

options.bundle

Contains information about the extension bundle, that is the container for all the extensions specified below. If required data is not specified here, grunt-cep will try to load it from the firstextension specified in the cep.extensions array.

version String Bundle version number (format: X.X.X).
id String Unique identifier for the bundle (used by Creative Cloud and Extension Manager). Usually provided in a form like com.developer_name.bundle_name.
name String Bundle name, displayed in Extension Manager.
author_name String Author or company name.
mxi_icon Object Bundle icon, displayed in Extension Manager. Icon should be a 23x23px PNG.
update_url String URL that contains extension XML update file and packages. Extension Manager will check for extension updates at {update_url}/update.xml and automatically download the updated package from {update_url}/{name}_{version}.zxp.
description String Description of the extension to display in the Extension Manager (supports HTML markup). This is only displayed if an URL is not entered in the description_href property.
description_href String A URL that points to a HTML file containing the description displayed in the Extension Manager when the extension bundle is selected. If provided description is not used.
ui_access String Description of how to access the extension, displayed in Extension Manager (supports HTML markup).
license_agreement String License agreement shown when installing the extension (supports HTML).
manifest String Bundle manifest file template, filled in at run-time with bundle information. You can one of the provided manifests (i.e. bundle/manifest.bundle.cc.xml) or provide your own. This is usually better specified in the builds array to allow per-product configuration (see example below).
files Array Since 0.3.0 - A list of additional files that will be added to the extension bundle. This is passed directly to Grunt and supports Grunt's Compact and Files Array formats. See Grunt documentation for additional information.

options.extensions

An array containing information about each single extension that will be added to the bundle. Each extension object holds information such as extension name, author, version, etc. The properties defined here are used to fill in manifest and other extension related file templates.

version String Extension version number (format: X.X.X).
id String Unique identifier for the extension (used by Creative Cloud and Extension Manager). Usually provided in a form like com.developer_name.bundle_name.extension_name.
name String Extension name displayed in the panel's header.
main_path String The extension entry point, usually index.html or similar.
script_path String Main ExtendScript file for the extension.
cef_params Array CEF command line parameters (see documentation for a list of supported parameters).
type String Extension type (i.e. "Panel", "ModalDialog", etc.).
lifecycle Object

Extension lifecycle setup. Holds two properties:

  • auto_visible (Boolean): true to make the extension's UI visible automatically when launched.
  • events (Array): an array of strings containing the events that can start the extension.
icons Object Extension icons, each icon should be a 23x23px PNG. Check the default values in the /options/defaults.js source file for a full description of the object.
size Object Panel dimensions (in pixels). Check the default values in the /options/defaults.js source file for a full description of the object.
manifest String Extension manifest file template, filled in at run-time with extension information. You can one of the provided manifests (i.e. bundle/manifest.extension.xml) or provide your own. This is usually better specified in the builds array to allow per-product configuration (see example below).

options.builds

The ability to specify single builds is one of the most powerful feature of grunt-cep when dealing with complex extension bundles.

The cep.builds property is an array of objects describing the various builds that should be executed, each one resulting in a separate ZXP file that will be bundled with the final ZXP installer.

Each build object contains the following properties and extends the main task configuration, giving you the ability to override base configuration values on a per-build basis.

products Array An array of strings containing the name of the products targeted by this build. Valid product names include: photoshop, illustrator, indesign, flash, dreamweaver, premiere, prelude.
families Array An array of strings containing the name of the product families targeted by this build. This can be useful to make sure an extension works across different Adobe Creative Cloud releases. Valid family names include: CC, CC2014.

options.launch

Only used when the launch profile is active, holds information needed to launch a target host application.

product String Host application to launch for debugging, defaults to the first one specified in the first build of the 'builds' array. Valid values are the same of builds.products.
family String Version of the host application to use for debugging, useful to test the extension in different releases of the same Adobe Creative Cloud application (i.e. while upgrading an extension from Adobe Photoshop CC to Adobe Photoshop CC 2014). If not specified, falls back to the first family specified in the current build. Valid family names include: CC, CC2014.
host_port Number

Default host port used for debug.

In order to support debugging an extension inside multiple products at the same time, each supported product will have an unique debug port assigned:

  • Photoshop: 8000
  • Illustrator: 8001
  • Etc. For a complete list, see the .debug file.

If bundling multiple extensions, each extension will have its debug port incremented by 100 (i.e. 8000, 8100, 8200, etc.)

options.package

Only used with the package profile, holds information related to bundle packaging and distribution.

mxi String Path to the MXI file template for this bundle. You can use the provided manifest template (bundle/template.mxi) or provide your own.
timestamp_url String Timestamp server URL, passed as -tsa option to ZXPSignCmd.
certificate Object

Holds information about the certificate used to sign the extension. It has two sub-properties:

  • file (String): path to the certificate file. If a valid certificate is not found at the specified location, a self-signed one is automatically generated using the password below.
  • password (String): certificate password.
update Object

When packaging an extension bundle, the task tries to find a changelog file named as the current extension version (x.x.x.txt) in the changelog_folder folder. This file is used to fill in the update.xml template file which can be used to support automatic updates for your extension through the Adobe Extension Manager CC application.

  • file (String): path to the update.xml file template (see below).
  • changelog_folder (String): path to the folder containing changelog files.
  • changelog_extension (String): changelog files extension.

Usage Examples

The example configuration below is based on the grunt-init-cep project template and defines an extension for Adobe Photoshop CC. It registers two tasks (debug and release) which respectively launch debug inside Adobe Photoshop CC and package the full extension.

All the icons and file templates referenced in the configuration are available in the project template (see the Getting Started section).

// cep-config.js
module.exports =
{
    bundle: {
        version: '0.1.0',
        id: 'com.foo.exampleBundle',
        name: 'Example Bundle',
        author_name: 'Foo',
        mxi_icon: 'bundle/icon-mxi.png',
    },
    
    extensions: [{
        version: '0.1.0',
        id: 'com.foo.exampleBundle.examplePanel',
        name: 'Example Panel',
        author_name: 'Foo',
        icons: {
            panel: {
                light: {
                    normal: 'icons/icon-light.png',
                    hover: 'icons/icon-light-hover.png',
                    disabled: 'icons/icon-light-disabled.png'
                },
                dark: {
                    normal: 'icons/icon-dark.png',
                    hover: 'icons/icon-dark-hover.png',
                    disabled: 'icons/icon-dark-disabled.png'
                },
            }
        },
        size: {
            normal: { width: 320, height: 440 },
            min: { width: 320, height: 440 },
            max: { width: 600, height: 600 },
        },
        main_path: 'example.html',
        script_path: 'extendscript/example.jsx',
    }],

    builds: [
        // Adobe Photoshop CC
        {
            bundle: { manifest: 'bundle/manifest.bundle.cc.xml' },
            extensions: [{ manifest: 'bundle/manifest.extension.xml' }],
            products: ['photoshop'],
            source: 'src',
        },
    ],

    'package': {
        certificate: {
            password: 'example_password',
        }
    },
};
// Grunfile.js
grunt.initConfig({

    // ...

    cep: {
        options: require('./cep-config.js'),

        debug: {
            options: { 
                profile: 'launch',
                launch: {
                    product: 'photoshop',
                },
            }
        },

        release: {
            options: { profile: 'package' }
        },
    },

    // ...
    
});

By running:

grunt cep:debug

grunt-cep will compile all the files in the src folders along with other extension files, install the resulting extension and launch Photoshop for testing.

If you want to package the Example extension just run:

grunt cep:release

and a compiled .ZXP file will be created in the staging folder.

Automatic Deploying

Something that I find particularly useful is the ability to automatically deploy the compiled extension to a website. This can be easily achieved using the grunt-ftp-deploy plugin:

grunt.initConfig({
    // grunt-cep
    cep: {
        // Your config here...
    },

    // FTP deploy
    "ftp-deploy": {
        release: {
            auth: {
                host: 'foo.it',
                port: 21,
                authKey: 'foo'
            },
            src: 'staging',
            dest: '/release',
            exclusions: ['debug', 'package', 'release'] // Exclude work directories
        },
    },
});

// Load plugins
grunt.loadNpmTasks('grunt-cep');
grunt.loadNpmTasks('grunt-ftp-deploy');

// Integrated packaging and deploying
grunt.registerTask('deploy', ['cep:release', 'ftp-deploy:release']);

When the deploy task is run, the cep:release task will package your extension and ftp-deploy will upload the relevant files (ZXP installer and "update.xml") to the foo.it website.

Contributing

Contributions are extremely welcome! Extension development for Adobe applications is a complex subject and has a lot of scarcely documented features and issues. Feel free to file issues or contribute fixes to code or documentation.

License

Copyright © 2014 Francesco Camarlinghi

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Copyrights & Trademarks

Based on code created by Creative Market. The included binaries are copyright Adobe Systems Incorporated. "Creative Suite" and "Creative Cloud" are registered trademarks of Adobe Systems Incorporated.