I write a lot of Services using Automator these days. They usually consist of one “Run Shell Script” action and possibly a few other Automator tasks. Editing a script in the Automator text fields is a horrible experience, so I end up doing a lot of copy-switch-pasting between my editor and Automator. This script lets me make the process simple.

You can find the script in this gist. It’s pretty simple to use.

If you run the script with the path to a .workflow file as the only argument, it will parse the file and return the configuration string for the “Run Shell Script” action. If there is more than one “Run Shell Script” action in the workflow, it will return a list of UUIDs you can copy and paste from.

In the external script that relates to that action, add a line:

# Workflow: [filepath, UUID]

You can put it anywhere in the file, and there can be multiple instances if the same script updates multiple Automator Workflows. You can also use // instead of #, depending on the comment syntax for the language your script is in.

When you run the contents of your script through update_workflow.rb (with no arguments), it will find the “Workflow:” lines and update the specified workflows/actions. You can test immediately without opening Automator. From the command line, this would look like cat script.rb | update_workflow.rb.

Side note: The script includes a version of the Ruby plist class with very minor modifications (to output non-indented PLISTs). This means you don’t need to install any gems to run it.

I have this set up as a Sublime Text build system, which is simply a matter of saving a file called Automator Workflow.sublime-build in your Packages/User/ folder with contents like this, edited to reflect your paths. When working on a script in Sublime, just choose “Automator Workflow” as your build system, and hit ⌘B whenever you want to update the workflow.