You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/06/29 20:37:41 UTC

[GitHub] csantanapr closed pull request #3816: Reorganize actions doc.

csantanapr closed pull request #3816: Reorganize actions doc.
URL: https://github.com/apache/incubator-openwhisk/pull/3816
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/docs/actions-docker.md b/docs/actions-docker.md
new file mode 100644
index 0000000000..8b4e8912be
--- /dev/null
+++ b/docs/actions-docker.md
@@ -0,0 +1,157 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+
+## Creating and invoking Docker actions
+
+With OpenWhisk Docker actions, you can write your actions in any language, bundle larger
+or complex dependencies, and tailor the runtime environment to suite your needs.
+
+- As a prerequisite, you must have a Docker Hub account.
+  To set up a free Docker ID and account, go to [Docker Hub](https://hub.docker.com).
+- The easiest way to get started with a Docker action is to use the OpenWhisk Docker skeleton.
+  - You can install the skeleton with the `wsk sdk install docker` CLI command.
+  - This is a a Docker image based on [python:3.6.1-alpine](https://hub.docker.com/r/library/python).
+  - The skeleton requires an entry point located at `/action/exec` inside the container.
+    This may be an executable script or binary compatible with this distribution.
+  - The executable receives the input arguments via a single command-line argument string
+    which can be deserialized as a `JSON` object.
+    It must return a result via `stdout` as a single-line string of serialized `JSON`.
+  - You may include any compilation steps or dependencies by modifying the `Dockerfile`
+    included in the `dockerSkeleton`.
+
+The instructions that follow show you how to use the OpenWhisk Docker skeleton.
+
+1. Install the Docker skeleton.
+
+  ```
+  wsk sdk install docker
+  ```
+  ```
+  The Docker skeleton is now installed at the current directory.
+  ```
+
+  ```
+  $ ls dockerSkeleton/
+  ```
+  ```
+  Dockerfile      README.md       buildAndPush.sh example.c
+  ```
+
+  The skeleton is a Docker container template where you can inject your code in the form of custom binaries.
+
+2. Create the executable. The Docker skeleton includes a C program that you can use as an example.
+
+  ```
+  cat dockerSkeleton/example.c
+  ```
+  ```c
+  #include <stdio.h>
+  int main(int argc, char *argv[]) {
+      printf("This is an example log message from an arbitrary C program!\n");
+      printf("{ \"msg\": \"Hello from arbitrary C program!\", \"args\": %s }",
+             (argc == 1) ? "undefined" : argv[1]);
+  }
+  ```
+
+  You can modify this file as needed, or, add additional code and dependencies to the Docker image.
+  In case of the latter, you may need to tweak the `Dockerfile` as necessary to build your executable.
+  The binary must be located inside the container at `/action/exec`.
+
+  The executable receives a single argument from the command line. It is a string serialization of the JSON
+  object representing the arguments to the action. The program may log to `stdout` or `stderr`.
+  By convention, the last line of output _must_ be a stringified JSON object which represents the result of
+  the action.
+
+3. Build the Docker image and upload it using a supplied script.
+  You must first run `docker login` to authenticate, and then run the script with a chosen image name.
+
+  ```
+  docker login -u janesmith -p janes_password
+  ```
+  ```
+  cd dockerSkeleton
+  ```
+  ```
+  ./buildAndPush.sh janesmith/blackboxdemo
+  ```
+
+  Notice that part of the example.c file is compiled as part of the Docker image build process,
+  so you do not need C compiled on your machine.
+  In fact, unless you are compiling the binary on a compatible host machine, it may not run inside
+  the container since formats will not match.
+
+  Your Docker container may now be used as an OpenWhisk action.
+
+  ```
+  wsk action create example --docker janesmith/blackboxdemo
+  ```
+
+  Notice the use of `--docker` when creating an action. Currently all Docker images are assumed
+  to be hosted on Docker Hub.
+
+## Invoking a Docker action
+
+Docker actions are invoked as [any other OpenWhisk action](actions.md#the-basics).
+
+  ```
+  wsk action invoke --result example --param payload Rey
+  ```
+  ```json
+  {
+      "args": {
+          "payload": "Rey"
+      },
+      "msg": "Hello from arbitrary C program!"
+  }
+  ```
+
+## Updating a Docker action
+
+To update the Docker action, run buildAndPush.sh again _and_ update your action.
+This will upload the latest image to Docker Hub and force the system to create a new container based on the image.
+If you do not update the action, then the image is pulled when there are no warm containers available for your action.
+A warm container will continue using a previous version of your Docker image,
+and any new invocations of the action will continue to use that image unless you run `wsk action update`.
+This will indicate to the system that for new invocations it should execute a docker pull to get your new Docker image.
+
+  ```
+  ./buildAndPush.sh janesmith/blackboxdemo
+  ```
+  ```
+  wsk action update example --docker janesmith/blackboxdemo
+  ```
+
+## Creating native actions
+
+Docker actions accept initialization data via a (zip) file, similar to other actions kinds.
+For example, the tutorial above created a binary executable inside the container located at `/action/exec`.
+If you copy this file to your local file system and zip it into `exec.zip` then you can use the following
+commands to create a docker action which receives the executable as initialization data.
+
+  ```bash
+  wsk action create example exec.zip --native
+  ```
+  which is equivalent to the following command.
+  ```bash
+  wsk action create example exec.zip --docker openwhisk/dockerskeleton
+  ```
+
+Using `--native`, you can see that any executable may be run as an OpenWhisk action.
+This includes `bash` scripts, or cross compiled binaries. For the latter, the constraint
+is that the binary must be compatible with the `openwhisk/dockerskeleton` image.
diff --git a/docs/actions-go.md b/docs/actions-go.md
new file mode 100644
index 0000000000..4e79821526
--- /dev/null
+++ b/docs/actions-go.md
@@ -0,0 +1,83 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+
+## Creating and invoking Go actions
+
+Using OpenWhisk [native actions](actions-docker.md#creating-native-actions),
+you can package any executable as an action. This works for Go as an example.
+As with [Docker actions](actions-docker.md), the Go executable receives a single argument
+from the command line.
+It is a string serialization of the JSON object representing the arguments to the action.
+The program may log to `stdout` or `stderr`.
+By convention, the last line of output _must_ be a stringified JSON object which represents
+the result of the action.
+
+Here is an example Go action.
+```go
+package main
+
+import "encoding/json"
+import "fmt"
+import "os"
+
+func main() {
+    //program receives one argument: the JSON object as a string
+    arg := os.Args[1]
+
+    // unmarshal the string to a JSON object
+    var obj map[string]interface{}
+    json.Unmarshal([]byte(arg), &obj)
+
+    // can optionally log to stdout (or stderr)
+    fmt.Println("hello Go action")
+
+    name, ok := obj["name"].(string)
+    if !ok { name = "Stranger" }
+
+    // last line of stdout is the result JSON object as a string
+    msg := map[string]string{"msg": ("Hello, " + name + "!")}
+    res, _ := json.Marshal(msg)
+    fmt.Println(string(res))
+}
+```
+
+Save the code above to a file `sample.go` and cross compile it for OpenWhisk.
+The executable must be called `exec`.
+```bash
+GOOS=linux GOARCH=amd64 go build -o exec
+zip exec.zip exec
+wsk action create helloGo --native exec.zip
+```
+
+The action may be run as any other action.
+```bash
+wsk action invoke helloGo -r -p name gopher
+{
+    "msg": "Hello, gopher!"
+}
+```
+
+Find out more about parameters in the [Working with parameters](./parameters.md) section.
+
+Logs are retrieved in a similar way as well.
+
+```bash
+  wsk activation logs --last --strip
+  my first Go action.
+```
diff --git a/docs/actions-java.md b/docs/actions-java.md
new file mode 100644
index 0000000000..e628344801
--- /dev/null
+++ b/docs/actions-java.md
@@ -0,0 +1,93 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+
+## Creating and invoking Java actions
+
+The process of creating Java actions is similar to that of [other actions](actions.md#the-basics).
+The following sections guide you through creating and invoking a single Java action,
+and demonstrate how to bundle multiple files and third party dependencies.
+
+In order to compile, test and archive Java files, you must have a
+[JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) installed locally.
+
+A Java action is a Java program with a method called `main` that has the exact signature as follows:
+```java
+public static com.google.gson.JsonObject main(com.google.gson.JsonObject);
+```
+
+For example, create a Java file called `Hello.java` with the following content:
+
+```java
+import com.google.gson.JsonObject;
+
+public class Hello {
+    public static JsonObject main(JsonObject args) {
+        String name = "stranger";
+        if (args.has("name"))
+            name = args.getAsJsonPrimitive("name").getAsString();
+        JsonObject response = new JsonObject();
+        response.addProperty("greeting", "Hello " + name + "!");
+        return response;
+    }
+}
+```
+
+Then, compile `Hello.java` into a JAR file `hello.jar` as follows:
+```
+javac Hello.java
+```
+```
+jar cvf hello.jar Hello.class
+```
+
+**Note:** [google-gson](https://github.com/google/gson) must exist in your Java CLASSPATH when compiling the Java file.
+
+You can create a OpenWhisk action called `helloJava` from this JAR file as
+follows:
+
+```
+wsk action create helloJava hello.jar --main Hello
+```
+
+When you use the command line and a `.jar` source file, you do not need to
+specify that you are creating a Java action;
+the tool determines that from the file extension.
+
+You need to specify the name of the main class using `--main`. An eligible main
+class is one that implements a static `main` method as described above. If the
+class is not in the default package, use the Java fully-qualified class name,
+e.g., `--main com.example.MyMain`.
+
+If needed you can also customize the method name of your Java action. This
+can be done by specifying the Java fully-qualified method name of your action,
+e.q., `--main com.example.MyMain#methodName`
+
+Action invocation is the same for Java actions as it is for Swift and JavaScript actions:
+
+```
+wsk action invoke --result helloJava --param name World
+```
+
+```json
+  {
+      "greeting": "Hello World!"
+  }
+```
+
+Find out more about parameters in the [Working with parameters](./parameters.md) section.
diff --git a/docs/actions-node.md b/docs/actions-node.md
new file mode 100644
index 0000000000..961834ef8e
--- /dev/null
+++ b/docs/actions-node.md
@@ -0,0 +1,400 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+
+## Creating and invoking JavaScript actions
+
+The process of creating JavaScript actions is similar to that of [other actions](actions.md#the-basics).
+The following sections guide you through creating and invoking a single JavaScript action,
+and demonstrate how to bundle multiple JavaScript files and third party dependencies.
+
+1. Create a JavaScript file with the following content. For this example, the file name is `hello.js`.
+
+  ```javascript
+  function main() {
+      return { msg: 'Hello world' };
+  }
+  ```
+
+  The JavaScript file might contain additional functions.
+  However, by convention, a function called `main` must exist to provide the entry point for the action.
+
+2. Create an action from the following JavaScript function. For this example, the action is called `hello`.
+
+  ```
+  wsk action create hello hello.js
+  ok: created action hello
+  ```
+
+  The CLI automatically infers the type of the action by using the source file extension.
+  For `.js` source files, the action runs by using a Node.js runtime. You may specify
+  the Node.js runtime to use by explicitly specifying the parameter `--kind nodejs:6` or `--kind nodejs:8`.
+
+
+## Creating asynchronous actions
+
+JavaScript functions that run asynchronously may need to return the activation result after the `main` function has returned. You can accomplish this by returning a Promise in your action.
+
+1. Save the following content in a file called `asyncAction.js`.
+
+  ```javascript
+  function main(args) {
+       return new Promise(function(resolve, reject) {
+         setTimeout(function() {
+           resolve({ done: true });
+         }, 2000);
+      })
+   }
+  ```
+
+  Notice that the `main` function returns a Promise, which indicates that the activation hasn't completed yet, but is expected to in the future.
+
+  The `setTimeout()` JavaScript function in this case waits for two seconds before calling the callback function.  This represents the asynchronous code and goes inside the Promise's callback function.
+
+  The Promise's callback takes two arguments, resolve and reject, which are both functions.  The call to `resolve()` fulfills the Promise and indicates that the activation has completed normally.
+
+  A call to `reject()` can be used to reject the Promise and signal that the activation has completed abnormally.
+
+2. Run the following commands to create the action and invoke it:
+
+  ```
+  wsk action create asyncAction asyncAction.js
+  ```
+  ```
+  wsk action invoke --result asyncAction
+  ```
+  ```json
+  {
+      "done": true
+  }
+  ```
+
+  Notice that you performed a blocking invocation of an asynchronous action.
+
+3. Fetch the activation log to see how long the activation took to complete:
+
+  ```
+  wsk activation list --limit 1 asyncAction
+  ```
+  ```
+  activations
+  b066ca51e68c4d3382df2d8033265db0             asyncAction
+  ```
+
+
+  ```
+  wsk activation get b066ca51e68c4d3382df2d8033265db0
+  ```
+ ```json
+  {
+      "start": 1455881628103,
+      "end":   1455881648126,
+      ...
+  }
+  ```
+
+  Comparing the `start` and `end` time stamps in the activation record, you can see that this activation took slightly over two seconds to complete.
+
+## Using actions to call an external API
+
+The examples so far have been self-contained JavaScript functions. You can also create an action that calls an external API.
+
+This example invokes a Yahoo Weather service to get the current conditions at a specific location.
+
+1. Save the following content in a file called `weather.js`.
+
+  ```javascript
+  var request = require('request');
+
+  function main(params) {
+      var location = params.location || 'Vermont';
+      var url = 'https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text="' + location + '")&format=json';
+
+      return new Promise(function(resolve, reject) {
+          request.get(url, function(error, response, body) {
+              if (error) {
+                  reject(error);
+              }
+              else {
+                  var condition = JSON.parse(body).query.results.channel.item.condition;
+                  var text = condition.text;
+                  var temperature = condition.temp;
+                  var output = 'It is ' + temperature + ' degrees in ' + location + ' and ' + text;
+                  resolve({msg: output});
+              }
+          });
+      });
+  }
+  ```
+
+  Note that the action in the example uses the JavaScript `request` library to make an HTTP request to the Yahoo Weather API, and extracts fields from the JSON result.
+  See the Javascript [reference](#reference) for the Node.js packages available in the runtime environment.
+
+  This example also shows the need for asynchronous actions. The action returns a Promise to indicate that the result of this action is not available yet when the function returns. Instead, the result is available in the `request` callback after the HTTP call completes, and is passed as an argument to the `resolve()` function.
+
+2. Create an action from the `weather.js` file:
+
+  ```
+  wsk action create weather weather.js
+  ```
+
+3. Use the following command to run the action, and observe the output:
+  ```
+  wsk action invoke --result weather --param location "Brooklyn, NY"
+  ```
+
+  Using the `--result` flag means that the value returned from the action is shown as output on the command-line:
+
+  ```json
+  {
+      "msg": "It is 28 degrees in Brooklyn, NY and Cloudy"
+  }
+  ```
+
+This example also passed a parameter to the action by using the `--param` flag and a value that can be changed each time the action is invoked. Find out more about parameters in the [Working with parameters](./parameters.md) section.
+
+## Packaging an action as a Node.js module
+
+As an alternative to writing all your action code in a single JavaScript source file, you can write an action as a `npm` package. Consider as an example a directory with the following files:
+
+First, `package.json`:
+
+```json
+{
+  "name": "my-action",
+  "main": "index.js",
+  "dependencies" : {
+    "left-pad" : "1.1.3"
+  }
+}
+```
+
+Then, `index.js`:
+
+```javascript
+function myAction(args) {
+    const leftPad = require("left-pad")
+    const lines = args.lines || [];
+    return { padded: lines.map(l => leftPad(l, 30, ".")) }
+}
+
+exports.main = myAction;
+```
+
+Note that the action is exposed through `exports.main`; the action handler itself can have any name, as long as it conforms to the usual signature of accepting an object and returning an object (or a `Promise` of an object). Per Node.js convention, you must either name this file `index.js` or specify the file name you prefer as the `main` property in package.json.
+
+To create an OpenWhisk action from this package:
+
+1. Install first all dependencies locally
+
+  ```
+  $ npm install
+  ```
+
+2. Create a `.zip` archive containing all files (including all dependencies):
+
+  ```
+  $ zip -r action.zip *
+  ```
+
+  > Please note: Using the Windows Explorer action for creating the zip file will result in an incorrect structure. OpenWhisk zip actions must have `package.json` at the root of the zip, while Windows Explorer will put it inside a nested folder. The safest option is to use the command line `zip` command as shown above.
+
+3. Create the action:
+
+  ```
+  wsk action create packageAction --kind nodejs:6 action.zip
+  ```
+
+  When creating an action from a `.zip` archive with the CLI tool, you must explicitly provide a value for the `--kind` flag by using `nodejs:6` or `nodejs:8`.
+
+4. You can invoke the action like any other:
+
+  ```
+  wsk action invoke --result packageAction --param lines "[\"and now\", \"for something completely\", \"different\" ]"
+  ```
+  ```json
+  {
+      "padded": [
+          ".......................and now",
+          "......for something completely",
+          ".....................different"
+      ]
+  }
+  ```
+
+Finally, note that while most `npm` packages install JavaScript sources on `npm install`, some also install and compile binary artifacts. The archive file upload currently does not support binary dependencies but rather only JavaScript dependencies. Action invocations may fail if the archive includes binary dependencies.
+
+### Package an action as a single bundle
+
+It is convenient to only include the minimal code into a single `.js` file that includes dependencies. This approach allows for faster deployments, and in some circumstances where packaging the action as a zip might be too large because it includes unnecessary files.
+
+You can use a JavaScript module bundler such as [webpack](https://webpack.js.org/concepts/). When webpack processes your code, it recursively builds a dependency graph that includes every module that your action needs.
+
+Here is a quick example using webpack:
+
+Taking the previous example `package.json` add `webpack` as a development dependency and add some npm script commands.
+```json
+{
+  "name": "my-action",
+  "main": "dist/bundle.js",
+  "scripts": {
+    "build": "webpack --config webpack.config.js",
+    "deploy": "wsk action update my-action dist/bundle.js --kind nodejs:8"
+  },
+  "dependencies": {
+    "left-pad": "1.1.3"
+  },
+  "devDependencies": {
+    "webpack": "^3.8.1"
+  }
+}
+```
+
+Create the webpack configuration file `webpack.config.js`.
+```javascript
+var path = require('path');
+module.exports = {
+  entry: './index.js',
+  output: {
+    path: path.resolve(__dirname, 'dist'),
+    filename: 'bundle.js'
+  },
+  target: 'node'
+};
+```
+
+Set the variable `global.main` to the main function of the action.
+From the previous example:
+```javascript
+function myAction(args) {
+    const leftPad = require("left-pad")
+    const lines = args.lines || [];
+    return { padded: lines.map(l => leftPad(l, 30, ".")) }
+}
+global.main = myAction;
+```
+
+If your function name is `main`, use this syntax instead:
+```javascript
+global.main = main;
+```
+
+To build and deploy an OpenWhisk Action using `npm` and `webpack`:
+
+1. First, install dependencies locally:
+
+  ```
+  npm install
+  ```
+
+2. Build the webpack bundle:
+
+  ```
+  npm run build
+  ```
+
+  The file `dist/bundle.js` is created, and is used to deploy as the Action source code.
+
+3. Create the Action using the `npm` script or the CLI.
+  Using `npm` script:
+  ```
+  npm run deploy
+  ```
+
+  Using the CLI:
+  ```
+  wsk action update my-action dist/bundle.js
+  ```
+
+Finally, the bundle file that is built by `webpack` doesn't support binary dependencies but rather JavaScript dependencies. So Action invocations will fail if the bundle depends on binary dependencies, because this is not included with the file `bundle.js`.
+
+
+## Reference
+
+JavaScript actions can be executed in Node.js version 6 or Node.js version 8.
+Currently actions are executed by default in a Node.js version 6 environment.
+
+### Node.js version 6 environment
+The Node.js 6.14.2 environment will be used for an action if the `--kind` flag is explicitly specified with a value of 'nodejs:6' when creating/updating the action.
+
+The following packages are available to be used in the Node.js 6.14.2 environment:
+
+- [apn v2.1.2](https://www.npmjs.com/package/apn) - A Node.js module for interfacing with the Apple Push Notification service.
+- [async v2.1.4](https://www.npmjs.com/package/async) - Provides functions for working with asynchronous functions.
+- [btoa v1.1.2](https://www.npmjs.com/package/btoa) - A port of the browser's btoa function.
+- [cheerio v0.22.0](https://www.npmjs.com/package/cheerio) - Fast, flexible & lean implementation of core jQuery designed specifically for the server.
+- [cloudant v1.6.2](https://www.npmjs.com/package/cloudant) - This is the official Cloudant library for Node.js.
+- [commander v2.9.0](https://www.npmjs.com/package/commander) - The complete solution for Node.js command-line interfaces.
+- [consul v0.27.0](https://www.npmjs.com/package/consul) - A client for Consul, involving service discovery and configuration.
+- [cookie-parser v1.4.3](https://www.npmjs.com/package/cookie-parser) - Parse Cookie header and populate req.cookies with an object keyed by the cookie names.
+- [cradle v0.7.1](https://www.npmjs.com/package/cradle) - A high-level, caching, CouchDB client for Node.js.
+- [errorhandler v1.5.0](https://www.npmjs.com/package/errorhandler) - Development-only error handler middleware.
+- [glob v7.1.1](https://www.npmjs.com/package/glob) - Match files by using patterns that the shell uses, like stars and stuff.
+- [gm v1.23.0](https://www.npmjs.com/package/gm) - GraphicsMagick and ImageMagick for Node.
+- [lodash v4.17.2](https://www.npmjs.com/package/lodash) - The Lodash library exported as Node.js modules.
+- [log4js v0.6.38](https://www.npmjs.com/package/log4js) - A conversion of the log4js framework designed to work with Node.
+- [iconv-lite v0.4.15](https://www.npmjs.com/package/iconv-lite) - Pure JS character encoding conversion
+- [marked v0.3.6](https://www.npmjs.com/package/marked) - A full-featured markdown parser and compiler, which is written in JavaScript. Built for speed.
+- [merge v1.2.0](https://www.npmjs.com/package/merge) - Merge multiple objects into one, optionally creating a new cloned object.
+- [moment v2.17.0](https://www.npmjs.com/package/moment) - A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
+- [mongodb v2.2.11](https://www.npmjs.com/package/mongodb) - The official MongoDB driver for Node.js.
+- [mustache v2.3.0](https://www.npmjs.com/package/mustache) - Mustache.js is an implementation of the mustache template system in JavaScript.
+- [nano v6.2.0](https://www.npmjs.com/package/nano) - Minimalistic couchdb driver for Node.js.
+- [node-uuid v1.4.7](https://www.npmjs.com/package/node-uuid) - Deprecated UUID packaged.
+- [nodemailer v2.6.4](https://www.npmjs.com/package/nodemailer) - Send e-mails from Node.js – easy as cake!
+- [oauth2-server v2.4.1](https://www.npmjs.com/package/oauth2-server) - Complete, compliant, and well tested module for implementing an OAuth2 Server/Provider with express in Node.js.
+- [openwhisk v3.15.0](https://www.npmjs.com/package/openwhisk) - JavaScript client library for the OpenWhisk platform. Provides a wrapper around the OpenWhisk APIs.
+- [pkgcloud v1.4.0](https://www.npmjs.com/package/pkgcloud) - pkgcloud is a standard library for Node.js that abstracts away differences among multiple cloud providers.
+- [process v0.11.9](https://www.npmjs.com/package/process) - Require('process'); just like any other module.
+- [pug v2.0.0-beta6](https://www.npmjs.com/package/pug) - Implements the Pug templating language.
+- [redis v2.6.3](https://www.npmjs.com/package/redis) - This is a complete and feature-rich Redis client for Node.js.
+- [request v2.79.0](https://www.npmjs.com/package/request) - Request is the simplest way possible to make HTTP calls.
+- [request-promise v4.1.1](https://www.npmjs.com/package/request-promise) - The simplified HTTP request client 'request' with Promise support. Powered by Bluebird.
+- [rimraf v2.5.4](https://www.npmjs.com/package/rimraf) - The UNIX command rm -rf for node.
+- [semver v5.3.0](https://www.npmjs.com/package/semver) - Supports semantic versioning.
+- [sendgrid v4.7.1](https://www.npmjs.com/package/sendgrid) - Provides email support via the SendGrid API.
+- [serve-favicon v2.3.2](https://www.npmjs.com/package/serve-favicon) - Node.js middleware for serving a favicon.
+- [socket.io v1.6.0](https://www.npmjs.com/package/socket.io) - Socket.IO enables real-time bidirectional event-based communication.
+- [socket.io-client v1.6.0](https://www.npmjs.com/package/socket.io-client) - Client-side support for Socket.IO.
+- [superagent v3.0.0](https://www.npmjs.com/package/superagent) - SuperAgent is a small progressive client-side HTTP request library, and Node.js module with the same API, sporting many high-level HTTP client features.
+- [swagger-tools v0.10.1](https://www.npmjs.com/package/swagger-tools) - Tools that are related to working with Swagger, a way to document APIs.
+- [tmp v0.0.31](https://www.npmjs.com/package/tmp) - A simple temporary file and directory creator for node.js.
+- [twilio v2.11.1](https://www.npmjs.com/package/twilio) - A wrapper for the Twilio API, related to voice, video, and messaging.
+- [underscore v1.8.3](https://www.npmjs.com/package/underscore) - Underscore.js is a utility-belt library for JavaScript that supports the usual functional suspects (each, map, reduce, filter...) without extending any core JavaScript objects.
+- [uuid v3.0.0](https://www.npmjs.com/package/uuid) - Simple, fast generation of RFC4122 UUIDS.
+- [validator v6.1.0](https://www.npmjs.com/package/validator) - A library of string validators and sanitizers.
+- [watson-developer-cloud v2.29.0](https://www.npmjs.com/package/watson-developer-cloud) - Node.js client library to use the Watson Developer Cloud services, a collection of APIs that use cognitive computing to solve complex problems.
+- [when v3.7.7](https://www.npmjs.com/package/when) - When.js is a rock solid, battle-tested Promises/A+ and when() implementation, including a complete ES6 Promise shim.
+- [winston v2.3.0](https://www.npmjs.com/package/winston) - A multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs."
+- [ws v1.1.1](https://www.npmjs.com/package/ws) - ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and server implementation.
+- [xml2js v0.4.17](https://www.npmjs.com/package/xml2js) - Simple XML to JavaScript object converter. It supports bi-directional conversion.
+- [xmlhttprequest v1.8.0](https://www.npmjs.com/package/xmlhttprequest) - node-XMLHttpRequest is a wrapper for the built-in http client to emulate the browser XMLHttpRequest object.
+- [yauzl v2.7.0](https://www.npmjs.com/package/yauzl) - Yet another unzip library for node. For zipping.
+
+### Node.js version 8 environment
+The Node.js version 8.11.2 environment is used if the `--kind` flag is explicitly specified with a value of 'nodejs:8' when creating or updating an Action.
+
+The following packages are pre-installed in the Node.js version 8.11.2 environment:
+
+- [openwhisk v3.15.0](https://www.npmjs.com/package/openwhisk) - JavaScript client library for the OpenWhisk platform. Provides a wrapper around the OpenWhisk APIs.
+
+### Packaging npm packages with your actions
+For any `npm` packages that are not pre-installed in the Node.js environment, you can bundle them as dependencies when you create or update your action.
+
+For more information, see [Packaging an action as a Node.js module](./actions.md#packaging-an-action-as-a-nodejs-module) or [Packaging an action as a single bundle](./actions.md#packaging-an-action-as-a-single-bundle).
+
diff --git a/docs/actions-php.md b/docs/actions-php.md
new file mode 100644
index 0000000000..7062e0cc42
--- /dev/null
+++ b/docs/actions-php.md
@@ -0,0 +1,120 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+
+## Creating and invoking PHP actions
+
+The process of creating PHP actions is similar to that of [other actions](actions.md#the-basics).
+The following sections guide you through creating and invoking a single PHP action,
+and demonstrate how to bundle multiple PHP files and third party dependencies.
+
+PHP actions are executed using PHP 7.1.18.
+To use this runtime, specify the `wsk` CLI parameter `--kind php:7.1` when creating or updating an action.
+This is the default when creating an action with file that has a `.php` extension.
+
+An action is simply a top-level PHP function. For example, create a file called `hello.php`
+with the following source code:
+
+```php
+<?php
+function main(array $args) : array
+{
+    $name = $args["name"] ?? "stranger";
+    $greeting = "Hello $name!";
+    echo $greeting;
+    return ["greeting" => $greeting];
+}
+```
+
+PHP actions always consume an associative array and return an associative array.
+The entry method for the action is `main` by default but may be specified explicitly when creating
+the action with the `wsk` CLI using `--main`, as with any other action type.
+
+You can create an OpenWhisk action called `helloPHP` from this function as follows:
+
+```
+wsk action create helloPHP hello.php
+```
+
+The CLI automatically infers the type of the action from the source file extension.
+For `.php` source files, the action runs using a PHP 7.1 runtime.
+
+Action invocation is the same for PHP actions as it is for [any other action](actions.md#the-basics).
+
+```
+wsk action invoke --result helloPHP --param name World
+```
+
+```json
+{
+  "greeting": "Hello World!"
+}
+```
+
+Find out more about parameters in the [Working with parameters](./parameters.md) section.
+
+## Packaging PHP actions in zip files
+
+You can package a PHP action along with other files and dependent packages in a zip file.
+The filename of the source file containing the entry point (e.g., `main`) must be `index.php`.
+For example, to create an action that includes a second file called `helper.php`,
+first create an archive containing your source files:
+
+```bash
+zip -r helloPHP.zip index.php helper.php
+```
+
+and then create the action:
+
+```bash
+wsk action create helloPHP --kind php:7.1 helloPHP.zip
+```
+
+## Including Composer dependencies
+
+If your PHP action requires [Composer](https://getcomposer.org) dependencies,
+you can install them as usual using `composer require` which will create a `vendor` directory.
+Add this directory to your action's zip file and create the action:
+
+```bash
+zip -r helloPHP.zip index.php vendor
+wsk action create helloPHP --kind php:7.1 helloPHP.zip
+```
+
+The PHP runtime will automatically include Composer's autoloader for you, so you can immediately
+use the dependencies in your action code. Note that if you don't include your own `vendor` folder,
+then the runtime will include one for you with the following Composer packages:
+
+- guzzlehttp/guzzle       v6.7.3
+- ramsey/uuid             v3.6.3
+
+## Built-in PHP extensions
+
+The following PHP extensions are available in addition to the standard ones:
+
+- bcmath
+- curl
+- gd
+- intl
+- mbstring
+- mysqli
+- pdo_mysql
+- pdo_pgsql
+- pdo_sqlite
+- soap
+- zip
diff --git a/docs/actions-python.md b/docs/actions-python.md
new file mode 100644
index 0000000000..561b7a0181
--- /dev/null
+++ b/docs/actions-python.md
@@ -0,0 +1,200 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+
+## Creating and invoking Python actions
+
+The process of creating Python actions is similar to that of [other actions](actions.md#the-basics).
+The following sections guide you through creating and invoking a single Python action,
+and demonstrate how to bundle multiple Python files and third party dependencies.
+
+An example action Python action is simply a top-level function.
+For example, create a file called `hello.py` with the following source code:
+
+```python
+def main(args):
+    name = args.get("name", "stranger")
+    greeting = "Hello " + name + "!"
+    print(greeting)
+    return {"greeting": greeting}
+```
+
+Python actions always consume a dictionary and produce a dictionary.
+The entry method for the action is `main` by default but may be specified explicitly when creating
+the action with the `wsk` CLI using `--main`, as with any other action type.
+
+You can create an OpenWhisk action called `helloPython` from this function as follows:
+
+```
+wsk action create helloPython hello.py
+```
+The CLI automatically infers the type of the action from the source file extension.
+For `.py` source files, the action runs using a Python 2.7 runtime.
+You can also create an action that runs with Python 3.6 by explicitly specifying the parameter
+`--kind python:3`.
+
+Action invocation is the same for Python actions as it is for any other actions:
+
+```
+wsk action invoke --result helloPython --param name World
+```
+
+```json
+  {
+      "greeting": "Hello World!"
+  }
+```
+
+Find out more about parameters in the [Working with parameters](./parameters.md) section.
+
+## Packaging Python actions in zip files
+
+You can package a Python action and dependent modules in a zip file.
+The filename of the source file containing the entry point (e.g., `main`) must be `__main__.py`.
+For example, to create an action with a helper module called `helper.py`, first create an archive containing your source files:
+
+```bash
+zip -r helloPython.zip __main__.py helper.py
+```
+
+and then create the action:
+
+```bash
+wsk action create helloPython --kind python:3 helloPython.zip
+```
+
+## Packaging Python actions with a virtual environment in zip files
+
+Another way of packaging Python dependencies is using a virtual environment (`virtualenv`). This allows you to link additional packages
+that may be installed via [`pip`](https://packaging.python.org/installing/) for example.
+To ensure compatibility with the OpenWhisk container, package installations inside a virtualenv must be done in the target environment.
+So the docker image `openwhisk/python2action` or `openwhisk/python3action` should be used to create a virtualenv directory for your action.
+
+As with basic zip file support, the name of the source file containing the main entry point must be `__main__.py`. In addition, the virtualenv directory must be named `virtualenv`.
+Below is an example scenario for installing dependencies, packaging them in a virtualenv, and creating a compatible OpenWhisk action.
+
+1. Given a `requirements.txt` file that contains the `pip` modules and versions to install, run the following to install the dependencies and create a virtualenv using a compatible Docker image:
+ ```bash
+ docker run --rm -v "$PWD:/tmp" openwhisk/python3action bash \
+   -c "cd tmp && virtualenv virtualenv && source virtualenv/bin/activate && pip install -r requirements.txt"
+ ```
+
+2. Archive the virtualenv directory and any additional Python files:
+ ```bash
+ zip -r helloPython.zip virtualenv __main__.py
+ ```
+
+3. Create the action:
+```bash
+wsk action create helloPython --kind python:3 helloPython.zip
+```
+
+While the steps above are shown for Python 3.6, you can do the same for Python 2.7 as well.
+
+## Python 3 actions
+
+Python 3 actions are executed using Python 3.6.1. To use this runtime, specify the `wsk` CLI parameter `--kind python:3` when creating or updating an action.
+The following packages are available for use by Python actions, in addition to the Python 3.6 standard libraries.
+
+- aiohttp v1.3.3
+- appdirs v1.4.3
+- asn1crypto v0.21.1
+- async-timeout v1.2.0
+- attrs v16.3.0
+- beautifulsoup4 v4.5.1
+- cffi v1.9.1
+- chardet v2.3.0
+- click v6.7
+- cryptography v1.8.1
+- cssselect v1.0.1
+- Flask v0.12
+- gevent v1.2.1
+- greenlet v0.4.12
+- httplib2 v0.9.2
+- idna v2.5
+- itsdangerous v0.24
+- Jinja2 v2.9.5
+- kafka-python v1.3.1
+- lxml v3.6.4
+- MarkupSafe v1.0
+- multidict v2.1.4
+- packaging v16.8
+- parsel v1.1.0
+- pyasn1 v0.2.3
+- pyasn1-modules v0.0.8
+- pycparser v2.17
+- PyDispatcher v2.0.5
+- pyOpenSSL v16.2.0
+- pyparsing v2.2.0
+- python-dateutil v2.5.3
+- queuelib v1.4.2
+- requests v2.11.1
+- Scrapy v1.1.2
+- service-identity v16.0.0
+- simplejson v3.8.2
+- six v1.10.0
+- Twisted v16.4.0
+- w3lib v1.17.0
+- Werkzeug v0.12
+- yarl v0.9.8
+- zope.interface v4.3.3
+
+## Python 2 actions
+
+Python 2 actions are executed using Python 2.7.12. This is the default runtime for Python actions, unless you specify the `--kind` flag when creating or updating an action. To explicitly select this runtime, use `--kind python:2`. The following packages are available for use by Python 2 actions, in addition to the Python 2.7 standard library.
+
+- appdirs v1.4.3
+- asn1crypto v0.21.1
+- attrs v16.3.0
+- beautifulsoup4 v4.5.1
+- cffi v1.9.1
+- click v6.7
+- cryptography v1.8.1
+- cssselect v1.0.1
+- enum34 v1.1.6
+- Flask v0.11.1
+- gevent v1.1.2
+- greenlet v0.4.12
+- httplib2 v0.9.2
+- idna v2.5
+- ipaddress v1.0.18
+- itsdangerous v0.24
+- Jinja2 v2.9.5
+- kafka-python v1.3.1
+- lxml v3.6.4
+- MarkupSafe v1.0
+- packaging v16.8
+- parsel v1.1.0
+- pyasn1 v0.2.3
+- pyasn1-modules v0.0.8
+- pycparser v2.17
+- PyDispatcher v2.0.5
+- pyOpenSSL v16.2.0
+- pyparsing v2.2.0
+- python-dateutil v2.5.3
+- queuelib v1.4.2
+- requests v2.11.1
+- Scrapy v1.1.2
+- service-identity v16.0.0
+- simplejson v3.8.2
+- six v1.10.0
+- Twisted v16.4.0
+- virtualenv v15.1.0
+- w3lib v1.17.0
+- Werkzeug v0.12
+- zope.interface v4.3.3
diff --git a/docs/actions-swift.md b/docs/actions-swift.md
new file mode 100644
index 0000000000..859583d18a
--- /dev/null
+++ b/docs/actions-swift.md
@@ -0,0 +1,306 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+
+## Creating and invoking Swift actions
+
+The process of creating Swift actions is similar to that of [other actions](actions.md#the-basics).
+The following sections guide you through creating and invoking a single Swift action,
+and demonstrate how to bundle multiple Swift files and third party dependencies.
+
+**Tip:** You can use the [Online Swift Playground](http://online.swiftplayground.run) to test your Swift code without having to install Xcode on your machine.
+
+**Note:** Swift actions run in a Linux environment. Swift on Linux is still in development,
+and OpenWhisk usually uses the latest available release, which is not necessarily stable.
+In addition, the version of Swift that is used with OpenWhisk might be inconsistent with versions
+of Swift from stable releases of Xcode on MacOS.
+
+### Swift 3
+An action is simply a top-level Swift function. For example, create a file called
+`hello.swift` with the following content:
+
+```swift
+func main(args: [String:Any]) -> [String:Any] {
+    if let name = args["name"] as? String {
+        return [ "greeting" : "Hello \(name)!" ]
+    } else {
+        return [ "greeting" : "Hello stranger!" ]
+    }
+}
+```
+In this example the Swift action consumes a dictionary and produces a dictionary.
+
+You can create an OpenWhisk action called `helloSwift` from this function as
+follows:
+
+```
+wsk action create helloSwift hello.swift --kind swift:3.1.1
+```
+
+### Swift 4
+
+New in Swift 4 in addition of the above main function signature there are two more signatures out of the box taking advantage of the [Codable](https://developer.apple.com/documentation/swift/codable) type. You can learn more about data types encodable and decodable for compatibility with external representations such as JSON [here](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types).
+
+The following takes as input parameter a Codable Input with field `name`, and returns a Codable output with a field `greetings`
+```swift
+struct Input: Codable {
+    let name: String?
+}
+struct Output: Codable {
+    let greeting: String
+}
+func main(param: Input, completion: (Output?, Error?) -> Void) -> Void {
+    let result = Output(greeting: "Hello \(param.name ?? "stranger")!")
+    print("Log greeting:\(result.greeting)")
+    completion(result, nil)
+}
+```
+In this example the Swift action consumes a Codable and produces a Codable type.
+If you don't need to handle any input you can use the function signature that doesn't take any input, only Codable output.
+```swift
+struct Output: Codable {
+    let greeting: String
+}
+func main(completion: (Output?, Error?) -> Void) -> Void {
+    let result = Output(greeting: "Hello OpenWhisk!")
+    completion(result, nil)
+}
+```
+
+
+You can create a OpenWhisk action called `helloSwift` from this function as
+follows:
+
+```
+wsk action create helloSwift hello.swift --kind swift:4.1
+```
+
+
+See the Swift [reference](#reference.md) for more information about the Swift runtime.
+
+Action invocation is the same for Swift actions as it is for JavaScript actions:
+
+```
+wsk action invoke --result helloSwift --param name World
+```
+
+```json
+  {
+      "greeting": "Hello World!"
+  }
+```
+
+Find out more about parameters in the [Working with parameters](./parameters.md) section.
+
+## Packaging an action as a Swift executable
+
+When you create an OpenWhisk Swift action with a Swift source file, it has to be compiled into a binary before the action is run. Once done, subsequent calls to the action are much faster until the container holding your action is purged. This delay is known as the cold-start delay.
+
+To avoid the cold-start delay, you can compile your Swift file into a binary and then upload to OpenWhisk in a zip file. As you need the OpenWhisk scaffolding, the easiest way to create the binary is to build it within the same environment as it will be run in.
+
+## Using a script to build Swift packaged action
+You can use a script to automate the packaging of the action. Create  script `compile.sh`h file the following.
+```bash
+#!/bin/bash
+set -ex
+
+if [ -z "$1" ] ; then
+    echo 'Error: Missing action name'
+    exit 1
+fi
+if [ -z "$2" ] ; then
+    echo 'Error: Missing kind, for example swift:4.1'
+    exit 2
+fi
+OUTPUT_DIR="build"
+if [ ${2} == "swift:3.1.1" ]; then
+  BASE_PATH="/swift3Action"
+  DEST_SOURCE="$BASE_PATH/spm-build"
+  RUNTIME="openwhisk/action-swift-v3.1.1"
+elif [ ${2} == "swift:4.1" ]; then
+  RUNTIME="openwhisk/action-swift-v4.1"
+  BASE_PATH="/swift4Action"
+  DEST_SOURCE="/$BASE_PATH/spm-build/Sources/Action"
+else
+  echo "Error: Kind $2 not recognize"
+  exit 3
+fi
+DEST_PACKAGE_SWIFT="$BASE_PATH/spm-build/Package.swift"
+
+BUILD_FLAGS=""
+if [ -n "$3" ] ; then
+    BUILD_FLAGS=${3}
+fi
+
+echo "Using runtime $RUNTIME to compile swift"
+docker run --rm --name=compile-ow-swift -it -v "$(pwd):/owexec" $RUNTIME bash -ex -c "
+
+if [ -f \"/owexec/$OUTPUT_DIR/$1.zip\" ] ; then
+    rm \"/owexec/$OUTPUT_DIR/$1.zip\"
+fi
+
+echo 'Setting up build...'
+cp /owexec/actions/$1/Sources/*.swift $DEST_SOURCE/
+
+# action file can be either {action name}.swift or main.swift
+if [ -f \"$DEST_SOURCE/$1.swift\" ] ; then
+    echo 'renaming $DEST_SOURCE/$1.swift $DEST_SOURCE/main.swift'
+    mv \"$DEST_SOURCE/$1.swift\" $DEST_SOURCE/main.swift
+fi
+# Add in the OW specific bits
+cat $BASE_PATH/epilogue.swift >> $DEST_SOURCE/main.swift
+echo '_run_main(mainFunction:main)' >> $DEST_SOURCE/main.swift
+
+# Only for Swift4
+if [ ${2} != "swift:3.1.1" ]; then
+  echo 'Adding wait to deal with escaping'
+  echo '_ = _whisk_semaphore.wait(timeout: .distantFuture)' >> $DEST_SOURCE/main.swift
+fi
+
+echo \"Compiling $1...\"
+cd /$BASE_PATH/spm-build
+cp /owexec/actions/$1/Package.swift $DEST_PACKAGE_SWIFT
+# we have our own Package.swift, do a full compile
+swift build ${BUILD_FLAGS} -c release
+
+echo 'Creating archive $1.zip...'
+#.build/release/Action
+mkdir -p /owexec/$OUTPUT_DIR
+zip \"/owexec/$OUTPUT_DIR/$1.zip\" .build/release/Action
+
+"
+```
+
+The script assumes you have a directory `actions` with each top level directory representing an action.
+```
+actions/
+├── hello
+│   ├── Package.swift
+│   └── Sources
+│       └── main.swift
+```
+
+- Create the `Package.swift` file to add dependencies.
+The syntax is different from Swift 3 to Swift 4 tools.
+For Swift 3 here is an example:
+  ```swift
+  import PackageDescription
+
+  let package = Package(
+    name: "Action",
+        dependencies: [
+            .Package(url: "https://github.com/apple/example-package-deckofplayingcards.git", majorVersion: 3),
+            .Package(url: "https://github.com/IBM-Swift/CCurl.git", "0.2.3"),
+            .Package(url: "https://github.com/IBM-Swift/Kitura-net.git", "1.7.10"),
+            .Package(url: "https://github.com/IBM-Swift/SwiftyJSON.git", "15.0.1"),
+            .Package(url: "https://github.com/watson-developer-cloud/swift-sdk.git", "0.16.0")
+        ]
+  )
+  ```
+  For Swift 4 here is an example:
+  ```swift
+  // swift-tools-version:4.0
+  import PackageDescription
+
+  let package = Package(
+      name: "Action",
+      products: [
+        .executable(
+          name: "Action",
+          targets:  ["Action"]
+        )
+      ],
+      dependencies: [
+        .package(url: "https://github.com/apple/example-package-deckofplayingcards.git", .upToNextMajor(from: "3.0.0"))
+      ],
+      targets: [
+        .target(
+          name: "Action",
+          dependencies: ["DeckOfPlayingCards"],
+          path: "."
+        )
+      ]
+  )
+  ```
+  As you can see this example adds `example-package-deckofplayingcards` as a dependency.
+  Notice that `CCurl`, `Kitura-net` and `SwiftyJSON` are provided in the standard Swift action
+and so you should include them in your own `Package.swift` only for Swift 3 actions.
+
+- Build the action by running the following command for a Swift 3 action:
+  ```
+  bash compile.sh hello swift:3.1.1
+  ```
+  To compile for Swift 4 use `swift:4.1` instead of `swift:3.1.1`
+  ```
+  bash compile.sh hello swift:4.1
+  ```
+  This has created hello.zip in the `build`.
+
+- Upload it to OpenWhisk with the action name helloSwifty:
+  For Swift 3 use the kind `swift:3.1.1`
+  ```
+  wsk action update helloSwiftly build/hello.zip --kind swift:3.1.1
+  ```
+  For Swift 4 use the kind `swift:3.1.1`
+  ```
+  wsk action update helloSwiftly build/hello.zip --kind swift:4.1
+  ```
+
+- To check how much faster it is, run
+  ```
+  wsk action invoke helloSwiftly --blocking
+  ```
+
+  The time it took for the action to run is in the "duration" property and compare to the time it takes to run with a compilation step in the hello action.
+
+## Error Handling in Swift 4
+
+With the new Codable completion handler, you can pass an Error to indicate a failure in your Action.
+[Error handling in Swift](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html) resembles exception handling in other languages, with the use of the `try, catch` and `throw` keywords.
+The following example shows a an example on handling an error
+```swift
+enum VendingMachineError: Error {
+    case invalidSelection
+    case insufficientFunds(coinsNeeded: Int)
+    case outOfStock
+}
+func main(param: Input, completion: (Output?, Error?) -> Void) -> Void {
+    // Return real error
+    do{
+        throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
+    } catch {
+        completion(nil, error)
+    }
+}
+```
+
+## Reference
+
+### Swift 3
+Swift 3 actions are executed using Swift 3.1.1  `--kind swift:3.1.1`.
+
+Swift 3.1.1 actions can use the following packages:
+- KituraNet version 1.7.6, https://github.com/IBM-Swift/Kitura-net
+- SwiftyJSON version 15.0.1, https://github.com/IBM-Swift/SwiftyJSON
+- Watson Developer Cloud SDK version 0.16.0, https://github.com/watson-developer-cloud/swift-sdk
+
+### Swift 4
+Swift 4 actions are executed using Swift 4.1  `--kind swift:4.1`.
+The default `--kind swift:default` is Swift 4.1.
+
+Swift 4.1 action runtime doesn't embed any packages, follow the instructions for [packaged swift actions](./actions.md#packaging-an-action-as-a-swift-executable) to include dependencies using a Package.swift.
diff --git a/docs/actions.md b/docs/actions.md
index 3a9867fc4f..0097b12208 100644
--- a/docs/actions.md
+++ b/docs/actions.md
@@ -17,1182 +17,387 @@
 #
 -->
 
-# Creating and invoking OpenWhisk actions
+# OpenWhisk Actions
 
 Actions are stateless functions that run on the OpenWhisk platform. For example, an action can
 be used to detect the faces in an image, respond to a database change, respond to an API call,
 or post a Tweet. In general, an action is invoked in response to an event and produces some
 observable output.
 
-An action may be created from a function programmed using a number of supported languages, or
-from a binary-compatible executable, or even executables packaged as Docker containers.
-
-_Prerequisite:_ The OpenWhisk CLI [`wsk`](https://github.com/apache/incubator-openwhisk-cli/releases)
-makes it easy to create and invoke actions. Instructions for configuring the CLI are available [here](???).
-
-Click on the language of your choice below to learn how to create and invoke an action using OpenWhisk for
-that language. If your preferred language isn't supported directly, you may find the
-[native binary](#creating-native-actions) or [Docker](#creating-docker-actions) action path more suitable.
-Multiple actions may be composed together to create a longer processing pipeline called a
-[sequence](#creating-action-sequences).
-
-* [JavaScript](#creating-and-invoking-javascript-actions)
-* [Swift](#creating-swift-actions)
-* [Python](#creating-python-actions)
-* [Java](#creating-java-actions)
-* [PHP](#creating-php-actions)
-* [Docker](#creating-docker-actions)
-* [Go](#creating-go-actions)
-* [Native binaries](#creating-native-actions)
-
-Each invocation of an action results in an activation record that is identified by a unique
-activation ID. The input to an action and the result of an action are a dictionary of key-value
-pairs, where the key is a string and the value a valid JSON value.
-
-In addition, we recommend that you review the following topics:
-
-* [Watching action output](#watching-action-output)
-* [Getting actions](#getting-actions)
-* [Listing actions](#listing-actions)
-* [Deleting actions](#deleting-actions)
-* [Accessing action metadata within the action body](#accessing-action-metadata-within-the-action-body)
-* [Securing your action](./security.md)
-
-## Creating and invoking JavaScript actions
-
-The following sections guide you through working with actions in JavaScript. You begin with the creation and invocation of a simple action. Then, you move on to adding parameters to an action and invoking that action with parameters. Then, you create asynchronous actions and, finally, work with action sequences.
-
-
-### Creating and invoking a simple JavaScript action
-
-Review the following steps and examples to create your first JavaScript action.
-
-1. Create a JavaScript file with the following content. For this example, the file name is 'hello.js'.
-
-  ```javascript
-  function main() {
-      return {payload: 'Hello world'};
-  }
-  ```
-
-  The JavaScript file might contain additional functions. However, by convention, a function called `main` must exist to provide the entry point for the action.
-
-2. Create an action from the following JavaScript function. For this example, the action is called 'hello'.
-
-  ```
-  wsk action create hello hello.js
-  ```
-  ```
-  ok: created action hello
-  ```
-  The CLI automatically infers the type of the action by using the source file extension. For `.js` source files, the action runs by using a Node.js 6 runtime. You can also create an action that runs with Node.js 8 by explicitly specifying the parameter `--kind nodejs:8`. For more information, see the Node.js 6 vs 8 [reference](./reference.md#javascript-runtime-environments).
-
-3. List the actions that you have created:
-
-  ```
-  wsk action list
-  ```
-  ```
-  actions
-  hello       private
-  ```
-
-  You can see the `hello` action you just created.
-
-4. After you create your action, you can run it in the cloud in OpenWhisk with the 'invoke' command. You can invoke actions with a *blocking* invocation (i.e., request/response style) or a *non-blocking* invocation by specifying a flag in the command. A blocking invocation request will _wait_ for the activation result to be available. The wait period is the lesser of 60 seconds or the action's configured [time limit](./reference.md#per-action-timeout-ms-default-60s). The result of the activation is returned if it is available within the wait period. Otherwise, the activation continues processing in the system and an activation ID is returned so that one may check for the result later, as with non-blocking requests (see [here](#watching-action-output) for tips on monitoring activations).
-
-  This example uses the blocking parameter, `--blocking`:
-
-  ```
-  wsk action invoke --blocking hello
-  ```
-  ```
-  ok: invoked hello with id 44794bd6aab74415b4e42a308d880e5b
-  ```
-  ```json
-  {
-      "result": {
-          "payload": "Hello world"
-      },
-      "status": "success",
-      "success": true
-  }
-  ```
-
-  The command outputs two important pieces of information:
-  * The activation ID (`44794bd6aab74415b4e42a308d880e5b`)
-  * The invocation result if it is available within the expected wait period
-
-  The result in this case is the string `Hello world` returned by the JavaScript function. The activation ID can be used to retrieve the logs or result of the invocation at a future time.
-
-5. If you don't need the action result right away, you can omit the `--blocking` flag to make a non-blocking invocation. You can get the result later by using the activation ID. See the following example:
-
-  ```
-  wsk action invoke hello
-  ```
-  ```
-  ok: invoked hello with id 6bf1f670ee614a7eb5af3c9fde813043
-  ```
-
-  ```
-  wsk activation result 6bf1f670ee614a7eb5af3c9fde813043
-  ```
-  ```json
-  {
-      "payload": "Hello world"
-  }
-  ```
-
-6. To access the most recent activation record, activation results or activation logs, use the `--last` or `-l` flag. Run the following command to get your last activation result.
-
-  ```
-  wsk activation result --last
-  ```
-  ```json
-  {
-      "payload": "Hello world"
-  }
-  ```
-
-  Note that you should not use an activation ID with the flag `--last`.
-
-7. If you forget to record the activation ID, you can get a list of activations ordered from the most recent to the oldest. Run the following command to get a list of your activations:
-
-  ```
-  wsk activation list
-  ```
-  ```
-  activations
-  44794bd6aab74415b4e42a308d880e5b         hello
-  6bf1f670ee614a7eb5af3c9fde813043         hello
-  ```
-
-### Creating asynchronous actions
-
-JavaScript functions that run asynchronously may need to return the activation result after the `main` function has returned. You can accomplish this by returning a Promise in your action.
-
-1. Save the following content in a file called `asyncAction.js`.
-
-  ```javascript
-  function main(args) {
-       return new Promise(function(resolve, reject) {
-         setTimeout(function() {
-           resolve({ done: true });
-         }, 2000);
-      })
-   }
-  ```
-
-  Notice that the `main` function returns a Promise, which indicates that the activation hasn't completed yet, but is expected to in the future.
-
-  The `setTimeout()` JavaScript function in this case waits for two seconds before calling the callback function.  This represents the asynchronous code and goes inside the Promise's callback function.
-
-  The Promise's callback takes two arguments, resolve and reject, which are both functions.  The call to `resolve()` fulfills the Promise and indicates that the activation has completed normally.
-
-  A call to `reject()` can be used to reject the Promise and signal that the activation has completed abnormally.
-
-2. Run the following commands to create the action and invoke it:
-
-  ```
-  wsk action create asyncAction asyncAction.js
-  ```
-  ```
-  wsk action invoke --result asyncAction
-  ```
-  ```json
-  {
-      "done": true
-  }
-  ```
-
-  Notice that you performed a blocking invocation of an asynchronous action.
-
-3. Fetch the activation log to see how long the activation took to complete:
-
-  ```
-  wsk activation list --limit 1 asyncAction
-  ```
-  ```
-  activations
-  b066ca51e68c4d3382df2d8033265db0             asyncAction
-  ```
-
-
-  ```
-  wsk activation get b066ca51e68c4d3382df2d8033265db0
-  ```
- ```json
-  {
-      "start": 1455881628103,
-      "end":   1455881648126,
-      ...
-  }
-  ```
-
-  Comparing the `start` and `end` time stamps in the activation record, you can see that this activation took slightly over two seconds to complete.
-
-### Using actions to call an external API
-
-The examples so far have been self-contained JavaScript functions. You can also create an action that calls an external API.
-
-This example invokes a Yahoo Weather service to get the current conditions at a specific location.
-
-1. Save the following content in a file called `weather.js`.
-
-  ```javascript
-  var request = require('request');
-
-  function main(params) {
-      var location = params.location || 'Vermont';
-      var url = 'https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text="' + location + '")&format=json';
-
-      return new Promise(function(resolve, reject) {
-          request.get(url, function(error, response, body) {
-              if (error) {
-                  reject(error);
-              }
-              else {
-                  var condition = JSON.parse(body).query.results.channel.item.condition;
-                  var text = condition.text;
-                  var temperature = condition.temp;
-                  var output = 'It is ' + temperature + ' degrees in ' + location + ' and ' + text;
-                  resolve({msg: output});
-              }
-          });
-      });
-  }
-  ```
-
-  Note that the action in the example uses the JavaScript `request` library to make an HTTP request to the Yahoo Weather API, and extracts fields from the JSON result. The [References](./reference.md#javascript-runtime-environments) detail the Node.js packages that you can use in your actions.
-
-  This example also shows the need for asynchronous actions. The action returns a Promise to indicate that the result of this action is not available yet when the function returns. Instead, the result is available in the `request` callback after the HTTP call completes, and is passed as an argument to the `resolve()` function.
-
-2. Create an action from the `weather.js` file:
-
-  ```
-  wsk action create weather weather.js
-  ```
-
-3. Use the following command to run the action, and observe the output:
-  ```
-  wsk action invoke --result weather --param location "Brooklyn, NY"
-  ```
-
-  Using the `--result` flag means that the value returned from the action is shown as output on the command-line:
-
-  ```json
-  {
-      "msg": "It is 28 degrees in Brooklyn, NY and Cloudy"
-  }
-  ```
+An action may be created from a function programmed using a number of [supported languages and runtimes](#languages-and-runtimes),
+or from a binary-compatible executable, or even executables packaged as Docker containers.
 
-This example also passed a parameter to the action by using the `--param` flag and a value that can be changed each time the action is invoked. Find out more about parameters in the [Working with parameters](./parameters.md) section.
+* The OpenWhisk CLI [`wsk`](https://github.com/apache/incubator-openwhisk-cli/releases)
+makes it easy to create and invoke actions. Instructions for configuring the CLI are available [here](cli.md).
+* You can also use the [REST API](rest_api.md).
 
-### Packaging an action as a Node.js module
+While the actual function code will be specific to a [language and runtime](#languages-and-runtimes),
+the OpenWhisk operations to create, invoke and manage an action are the same regardless of the
+implementation choice. We recommend that you review [the basics](#the-basics) before moving on to
+advanced topics.
 
-As an alternative to writing all your action code in a single JavaScript source file, you can write an action as a `npm` package. Consider as an example a directory with the following files:
-
-First, `package.json`:
-
-```json
-{
-  "name": "my-action",
-  "main": "index.js",
-  "dependencies" : {
-    "left-pad" : "1.1.3"
-  }
+* [The basics of working with actions](#the-basics) (_start here_)
+* Common `wsk` CLI operations and tips
+  * [Watching action output](#watching-action-output)
+  * [Getting actions](#getting-actions)
+  * [Listing actions](#listing-actions)
+  * [Deleting actions](#deleting-actions)
+* [Accessing action metadata within the action body](#accessing-action-metadata-within-the-action-body)
+* [Securing your action](security.md)
+
+## Languages and Runtimes
+
+Longer tutorials that are specific to a language of your choice are listed below.
+We recommend reading the basics in this document first, which are language agnostic, before getting deeper
+into a language-specific tutorial. If your preferred language isn't supported directly, you may find
+the [Docker](docker-actions.md) action or [native binary](docker-actions.md#creating-native-actions)
+paths more suitable. Multiple actions may be composed together to create a longer processing pipeline called a
+[sequence](#creating-action-sequences). A more advanced form of composition is described [here](conductors.md).
+
+* [JavaScript](actions-node.md)
+* [Python](actions-python.md)
+* [Java](actions-java.md)
+* [PHP](actions-php.md)
+* [Swift](actions-swift.md)
+* [Docker and native binaries](actions-docker.md)
+* [Go](actions-go.md)
+
+## The basics
+
+To use a function as an action, it must conform to the following:
+- The function accepts a dictionary as input and produces a dictionary as output. The input and output dictionaries are
+key-value pairs, where the key is a string and the value is any valid JSON value. The dictionaries are
+canonically represented as JSON objects when interfacing to an action via the REST API or the `wsk` CLI.
+- The function must be called `main` or otherwise must be explicitly exported to identify it as the entry point.
+The mechanics may vary depending on your choice of language, but in general the entry point can be specified using the
+`--main` flag when using the `wsk` CLI.
+
+In this section, you'll invoke a built-in action using the `wsk` CLI, which you should
+[download and configure](cli.md) first if necessary.
+
+### Invoking a built-in action
+
+Actions are identified by [fully qualified names](reference.md#fully-qualified-names) which generally have
+three parts separated by a forward slash:
+1. a namespace
+2. a package name
+3. the action name
+
+As an example, we will work with a built-in sample action called `/whisk.system/samples/greeting`.
+The namespace for this action is `whisk.system`, the package name
+is `samples`, and the action name is `greeting`. There are other sample actions and
+utility actions, and later you'll learn how to explore the platform to discover more actions.
+You can learn more about [packages](packages.md) after completing the basic tutorial.
+
+Let's take a look at the action body by saving the function locally:
+```
+wsk action get /whisk.system/samples/greeting --save
+ok: saved action code to /path/to/openwhisk/greeting.js
+```
+
+This is a JavaScript function, which is indicated by the `.js` extension.
+It will run using a [Node.js](http://nodejs.org/) runtime.
+See [supported languages and runtimes](#languages-and-runtimes) for other languages and runtimes.
+
+The contents of the file `greeting.js` should match the function below. It is a short function which
+accepts optional parameters and returns a standard greeting.
+
+```js
+/**
+ * @params is a JSON object with optional fields "name" and "place".
+ * @return a JSON object containing the message in a field called "msg".
+ */
+function main(params) {
+  // log the paramaters to stdout
+  console.log('params:', params);
+
+  // if a value for name is provided, use it else use a default
+  var name = params.name || 'stranger';
+
+  // if a value for place is provided, use it else use a default
+  var place = params.place || 'somewhere';
+
+  // construct the message using the values for name and place
+  return {msg:  'Hello, ' + name + ' from ' + place + '!'};
 }
 ```
 
-Then, `index.js`:
-
-```javascript
-function myAction(args) {
-    const leftPad = require("left-pad")
-    const lines = args.lines || [];
-    return { padded: lines.map(l => leftPad(l, 30, ".")) }
-}
-
-exports.main = myAction;
+The command to invoke an action and get its result is `wsk action invoke <name> --result` as in:
+```
+wsk action invoke /whisk.system/samples/greeting --result
 ```
 
-Note that the action is exposed through `exports.main`; the action handler itself can have any name, as long as it conforms to the usual signature of accepting an object and returning an object (or a `Promise` of an object). Per Node.js convention, you must either name this file `index.js` or specify the file name you prefer as the `main` property in package.json.
-
-To create an OpenWhisk action from this package:
-
-1. Install first all dependencies locally
-
-  ```
-  $ npm install
-  ```
-
-2. Create a `.zip` archive containing all files (including all dependencies):
-
-  ```
-  $ zip -r action.zip *
-  ```
-
-  > Please note: Using the Windows Explorer action for creating the zip file will result in an incorrect structure. OpenWhisk zip actions must have `package.json` at the root of the zip, while Windows Explorer will put it inside a nested folder. The safest option is to use the command line `zip` command as shown above.
-
-3. Create the action:
-
-  ```
-  wsk action create packageAction --kind nodejs:6 action.zip
-  ```
-
-  When creating an action from a `.zip` archive with the CLI tool, you must explicitly provide a value for the `--kind` flag by using `nodejs:6` or `nodejs:8`.
-
-4. You can invoke the action like any other:
-
-  ```
-  wsk action invoke --result packageAction --param lines "[\"and now\", \"for something completely\", \"different\" ]"
-  ```
-  ```json
-  {
-      "padded": [
-          ".......................and now",
-          "......for something completely",
-          ".....................different"
-      ]
-  }
-  ```
-
-Finally, note that while most `npm` packages install JavaScript sources on `npm install`, some also install and compile binary artifacts. The archive file upload currently does not support binary dependencies but rather only JavaScript dependencies. Action invocations may fail if the archive includes binary dependencies.
-
-### Package an action as a single bundle
-
-It is convenient to only include the minimal code into a single `.js` file that includes dependencies. This approach allows for faster deployments, and in some circumstances where packaging the action as a zip might be too large because it includes unnecessary files.
-
-You can use a JavaScript module bundler such as [webpack](https://webpack.js.org/concepts/). When webpack processes your code, it recursively builds a dependency graph that includes every module that your action needs.
-
-Here is a quick example using webpack:
-
-Taking the previous example `package.json` add `webpack` as a development dependency and add some npm script commands.
+This command will print the following result to the terminal:
 ```json
 {
-  "name": "my-action",
-  "main": "dist/bundle.js",
-  "scripts": {
-    "build": "webpack --config webpack.config.js",
-    "deploy": "wsk action update my-action dist/bundle.js --kind nodejs:8"
-  },
-  "dependencies": {
-    "left-pad": "1.1.3"
-  },
-  "devDependencies": {
-    "webpack": "^3.8.1"
-  }
-}
-```
-
-Create the webpack configuration file `webpack.config.js`.
-```javascript
-var path = require('path');
-module.exports = {
-  entry: './index.js',
-  output: {
-    path: path.resolve(__dirname, 'dist'),
-    filename: 'bundle.js'
-  },
-  target: 'node'
-};
-```
-
-Set the variable `global.main` to the main function of the action.
-From the previous example:
-```javascript
-function myAction(args) {
-    const leftPad = require("left-pad")
-    const lines = args.lines || [];
-    return { padded: lines.map(l => leftPad(l, 30, ".")) }
+  "msg": "Hello, stranger from somewhere!"
 }
-global.main = myAction;
 ```
 
-If your function name is `main`, use this syntax instead:
-```javascript
-global.main = main;
-```
-
-To build and deploy an OpenWhisk Action using `npm` and `webpack`:
-
-1. First, install dependencies locally:
-
-  ```
-  npm install
-  ```
-
-2. Build the webpack bundle:
-
-  ```
-  npm run build
-  ```
-
-  The file `dist/bundle.js` is created, and is used to deploy as the Action source code.
+### Passing parameters to actions
 
-3. Create the Action using the `npm` script or the CLI.
-  Using `npm` script:
-  ```
-  npm run deploy
-  ```
-
-  Using the CLI:
-  ```
-  wsk action update my-action dist/bundle.js
-  ```
-
-Finally, the bundle file that is built by `webpack` doesn't support binary dependencies but rather JavaScript dependencies. So Action invocations will fail if the bundle depends on binary dependencies, because this is not included with the file `bundle.js`.
-
-## Creating action sequences
-
-You can create an action that chains together a sequence of actions.
-
-Several utility actions are provided in a package called `/whisk.system/utils` that you can use to create your first sequence. You can learn more about packages in the [Packages](./packages.md) section.
-
-1. Display the actions in the `/whisk.system/utils` package.
-
-  ```
-  wsk package get --summary /whisk.system/utils
-  ```
-  ```
-  package /whisk.system/utils: Building blocks that format and assemble data
-   (parameters: none defined)
-     action /whisk.system/utils/namespace: Returns namespace for the authorization key used to invoke this action
-       (parameters: none defined)
-     action /whisk.system/utils/date: Current date and time
-       (parameters: none defined)
-     action /whisk.system/utils/sort: Sorts an array
-       (parameters: lines)
-     action /whisk.system/utils/split: Split a string into an array
-       (parameters: payload, separator)
-     action /whisk.system/utils/hosturl: Returns the URL to activation an action or trigger
-       (parameters: ext, path, trigger, web)
-     ...
-  ```
-
-  You will be using the `split` and `sort` actions in this example.
-
-2. Create an action sequence so that the result of one action is passed as an argument to the next action.
-
-  ```
-  wsk action create sequenceAction --sequence /whisk.system/utils/split,/whisk.system/utils/sort
-  ```
-
-  This action sequence converts some lines of text to an array, and sorts the lines.
-
-3. Invoke the action:
-
-  ```
-  wsk action invoke --result sequenceAction --param payload "Over-ripe sushi,\nThe Master\nIs full of regret."
-  ```
-  ```json
-  {
-      "length": 3,
-      "lines": [
-          "Is full of regret.",
-          "Over-ripe sushi,",
-          "The Master"
-      ]
-  }
-  ```
-
-  In the result, you see that the lines are sorted.
-
-**Note**: Parameters passed between actions in the sequence are explicit, except for default parameters.
-Therefore parameters that are passed to the action sequence are only available to the first action in the sequence.
-The result of the first action in the sequence becomes the input JSON object to the second action in the sequence (and so on).
-This object does not include any of the parameters originally passed to the sequence unless the first action explicitly includes them in its result.
-Input parameters to an action are merged with the action's default parameters, with the former taking precedence and overriding any matching default parameters.
-For more information about invoking action sequences with multiple named parameters, see [Setting default parameters](./parameters.md#setting-default-parameters).
-
-## Creating Python actions
-
-The process of creating Python actions is similar to that of JavaScript actions. The following sections guide you through creating and invoking a single Python action, and packaging your actions in zip files.
-
-### Creating and invoking a Python action
-
-An action is simply a top-level Python function. For example, create a file called `hello.py` with the following source code:
-
-```python
-def main(args):
-    name = args.get("name", "stranger")
-    greeting = "Hello " + name + "!"
-    print(greeting)
-    return {"greeting": greeting}
-```
-
-Python actions always consume a dictionary and produce a dictionary. The entry method for the action is `main` by default but may be specified explicitly when creating the action with the `wsk` CLI using `--main`, as with any other action type.
-
-You can create an OpenWhisk action called `helloPython` from this function as follows:
-
-```
-wsk action create helloPython hello.py
-```
-The CLI automatically infers the type of the action from the source file extension. For `.py` source files, the action runs using a Python 2.7 runtime. You can also create an action that runs with Python 3.6 by explicitly specifying the parameter `--kind python:3`. See the Python [reference](./reference.md#python-actions) for more information about Python 2.7 vs. 3.6.
+Actions may receive parameters as input, and the `wsk` CLI makes it convenient to pass parameters to the actions
+from the command line. Briefly, this is done with the flag `--param key value` where `key` is the property name and `value` is
+any valid JSON value. There is a longer [tutorial on working with parameters](parameters.md) that you should read after completing
+this basic walk-through.
 
-Action invocation is the same for Python actions as it is for JavaScript actions:
+The `/whisk.system/samples/greeting` action accepts two optional input arguments, which are used to tailor the
+response. The default greeting as described earlier is "Hello, stranger from somewhere!". The words "stranger" and
+"somewhere" may be replaced by specifying the following parameters respectively:
+- `name` whose value will replace the word "stranger",
+- `place` whose value will replace the word "somewhere".
 
 ```
-wsk action invoke --result helloPython --param name World
-```
-
-```json
-  {
-      "greeting": "Hello World!"
-  }
-```
-
-Find out more about parameters in the [Working with parameters](./parameters.md) section.
-
-### Packaging Python actions in zip files
-
-You can package a Python action and dependent modules in a zip file.
-The filename of the source file containing the entry point (e.g., `main`) must be `__main__.py`.
-For example, to create an action with a helper module called `helper.py`, first create an archive containing your source files:
-
-```bash
-zip -r helloPython.zip __main__.py helper.py
-```
-
-and then create the action:
-
-```bash
-wsk action create helloPython --kind python:3 helloPython.zip
+wsk action invoke /whisk.system/samples/greeting --result --param name Dorothy --param place Kansas
+{
+  "msg": "Hello, Dorothy from Kansas!"
+}
 ```
 
-### Packaging Python actions with a virtual environment in zip files
+### Request-Response vs Fire-and-Forget
 
-Another way of packaging Python dependencies is using a virtual environment (`virtualenv`). This allows you to link additional packages
-that may be installed via [`pip`](https://packaging.python.org/installing/) for example.
-To ensure compatibility with the OpenWhisk container, package installations inside a virtualenv must be done in the target environment.
-So the docker image `openwhisk/python2action` or `openwhisk/python3action` should be used to create a virtualenv directory for your action.
+The style of invocation shown above is synchronous in that the request from the CLI _blocks_ until the
+activation completes and the result is available from the OpenWhisk platform. This is generally useful
+for rapid iteration and development.
 
-As with basic zip file support, the name of the source file containing the main entry point must be `__main__.py`. In addition, the virtualenv directory must be named `virtualenv`.
-Below is an example scenario for installing dependencies, packaging them in a virtualenv, and creating a compatible OpenWhisk action.
+You can invoke an action asynchronously as well, by dropping the `--result` command line option. In this case
+the action is invoked, and the OpenWhisk platform returns an activation ID which you can use later to retrieve
+the activation record.
 
-1. Given a `requirements.txt` file that contains the `pip` modules and versions to install, run the following to install the dependencies and create a virtualenv using a compatible Docker image:
- ```bash
- docker run --rm -v "$PWD:/tmp" openwhisk/python3action bash \
-   -c "cd tmp && virtualenv virtualenv && source virtualenv/bin/activate && pip install -r requirements.txt"
  ```
-
-2. Archive the virtualenv directory and any additional Python files:
- ```bash
- zip -r helloPython.zip virtualenv __main__.py
+wsk action invoke /whisk.system/samples/greeting
+ok: invoked /whisk.system/samples/greeting with id 5a64676ec8aa46b5a4676ec8aaf6b5d2
  ```
 
-3. Create the action:
-```bash
-wsk action create helloPython --kind python:3 helloPython.zip
+To retrieve the activation record, you use the `wsk activations get <id>` command, as in:
 ```
-
-While the steps above are shown for Python 3.6, you can do the same for Python 2.7 as well.
-
-
-## Creating PHP actions
-
-The process of creating PHP actions is similar to that of JavaScript actions. The following sections guide you through creating and invoking a single PHP action, and demonstrate how to zip your PHP actions.
-
-### Creating and invoking a PHP action
-
-An action is simply a top-level PHP function. For example, create a file called `hello.php` with the following source code:
-
-```php
-<?php
-function main(array $args) : array
+wsk activation get 5a64676ec8aa46b5a4676ec8aaf6b5d2
+ok: got activation 5a64676ec8aa46b5a4676ec8aaf6b5d2
 {
-    $name = $args["name"] ?? "stranger";
-    $greeting = "Hello $name!";
-    echo $greeting;
-    return ["greeting" => $greeting];
+  "activationId": "5a64676ec8aa46b5a4676ec8aaf6b5d2",
+  "duration": 3,
+  "response": {
+    "result": {
+      "msg": "Hello, stranger from somewhere!"
+    },
+    "status": "success",
+    "success": true
+  }, ...
 }
 ```
 
-PHP actions always consume an associative array and return an associative array. The entry method for the action is `main` by default but may be specified explicitly when creating the action with the `wsk` CLI using `--main`, as with any other action type.
-
-You can create an OpenWhisk action called `helloPHP` from this function as follows:
+Sometimes it is helpful to invoke an action in a blocking style and receiving the activation record entirely
+instead of just the result. This is achieved using the `--blocking` command line parameter.
 
 ```
-wsk action create helloPHP hello.php
+wsk action invoke /whisk.system/samples/greeting --blocking
+ok: invoked /whisk.system/samples/greeting with id 5975c24de0114ef2b5c24de0118ef27e
+{
+  "activationId": "5975c24de0114ef2b5c24de0118ef27e",
+  "duration": 3,
+  "response": {
+    "result": {
+      "msg": "Hello, stranger from somewhere!"
+    },
+    "status": "success",
+    "success": true
+  }, ...
+}
 ```
 
-The CLI automatically infers the type of the action from the source file extension. For `.php` source files, the action runs using a PHP 7.1 runtime. See the PHP [reference](./reference.md#php-actions) for more information.
+### Blocking invocations and timeouts
 
-Action invocation is the same for PHP actions as it is for JavaScript actions:
+A blocking invocation request will _wait_ for the activation result to be available. The wait period
+is the lesser of 60 seconds or the action's configured
+[time limit](reference.md#per-action-timeout-ms-default-60s).
+The result of the activation is returned if it is available within the wait period.
+Otherwise, the activation continues processing in the system and an activation ID is returned
+so that one may check for the result later, as with non-blocking requests
+(see [here](#watching-action-output) for tips on monitoring activations).
 
-```
-wsk action invoke --result helloPHP --param name World
-```
+### Understanding the activation record
 
-```json
-  {
-      "greeting": "Hello World!"
-  }
-```
+Each action invocation results in an activation record which contains the following fields:
 
-Find out more about parameters in the [Working with parameters](./parameters.md) section.
+- `activationId`: The activation ID.
+- `namespace` and `name`: The namespace and name of the entity.
+- `start` and `end`: Timestamps recording the start and end of the activation. The values are in [UNIX time format](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15).
+- `logs`: An array of strings with the logs that are produced by the action during its activation. Each array element corresponds to a line output to `stdout` or `stderr` by the action, and includes the time and stream of the log output. The structure is as follows: `TIMESTAMP` `STREAM:` `LOG LINE`.
+- `annotations`: An array of key-value pairs that record [metadata](annotations.md#annotations-specific-to-activations) about the action activation.
+- `response`: A dictionary that defines the following keys
+  - `status`: The activation result, which might be one of the following values:
+    - *"success"*: the action invocation completed successfully.
+    - *"application error"*: the action invocation was successful, but the action returned an error value on purpose, for instance because a precondition on the arguments was not met.
+    - *"action developer error"*: the action was invoked, but it completed abnormally, for instance the action did not detect an exception, or a syntax error existed.
+    - *"whisk internal error"*: the system was unable to invoke the action.
+  - `success`: Is *true* if and only if the status is *"success"*.
+  - `result`: A dictionary as a JSON object which contains the activation result. If the activation was successful, this contains the value that is returned by the action. If the activation was unsuccessful, `result` contains the `error` key, generally with an explanation of the failure.
 
-### Packaging PHP actions in zip files
+Some common CLI commands for working with activations are:
+- `wsk activation list`: lists all activations
+- `wsk activation get --last`: retrieves the most recent activation record
+- `wsk activation result <activationId>`: retrieves only the result of the activation (or use `--last` to get the most recent result).
+- `wsk activation logs <activationId>`: retrieves only the logs of the activation.
+- `wsk activation logs <activationId> --strip`: strips metadata from each log line so the logs are easier to read.
 
-You can package a PHP action along with other files and dependent packages in a zip file.
-The filename of the source file containing the entry point (e.g., `main`) must be `index.php`.
-For example, to create an action that includes a second file called `helper.php`, first create an archive containing your source files:
+### Creating and updating your own action
 
-```bash
-zip -r helloPHP.zip index.php helper.php
+Earlier we saved the code from the `greeting` action locally. We can use it to create our own version of the action
+in our own namespace.
 ```
-
-and then create the action:
-
-```bash
-wsk action create helloPHP --kind php:7.1 helloPHP.zip
+wsk action create greeting greeting.js
+ok: created action greeting
 ```
 
-### Including Composer dependencies
-
-If your PHP action requires [Composer](https://getcomposer.org) dependencies, you can install them as usual using `composer require` which will create a `vendor` directory. Add this directory to your action's zip file and create the action:
+For convenience, you can omit the namespace when working with actions that belong to you. Also if there
+is no package, then you simply use the action name without a [package](packages.md) name.
+If you modify the code and want to update the action, you can use `wsk action update` instead of
+`wsk action create`. The two commands are otherwise the same in terms of their command like parameters.
 
-```bash
-zip -r helloPHP.zip index.php vendor
-wsk action create helloPHP --kind php:7.1 helloPHP.zip
 ```
-
-The PHP runtime will automatically include Composer's autoloader for you, so you can immediately use the dependencies in your action code.
-
-Note that if you don't include your own `vendor` folder, then the runtime will include one for you. The packages included are listed in the [reference](https://github.com/apache/incubator-openwhisk/blob/master/docs/reference.md#composer-packages).
-
-
-## Creating Swift actions
-
-The process of creating Swift actions is similar to that of JavaScript actions. The following sections guide you through creating and invoking a single swift action, and packaging an action in a zip file.
-
-You can also use the online [Online Swift Playground](http://online.swiftplayground.run) to test your Swift code without having to install Xcode on your machine.
-
-**Attention:** Swift actions run in a Linux environment. Swift on Linux is still in
-development, and OpenWhisk usually uses the latest available release, which is not necessarily stable. In addition, the version of Swift that is used with OpenWhisk might be inconsistent with versions of Swift from stable releases of Xcode on MacOS.
-
-### Creating and invoking an action
-
-#### Swift 3
-An action is simply a top-level Swift function. For example, create a file called
-`hello.swift` with the following content:
-
-```swift
-func main(args: [String:Any]) -> [String:Any] {
-    if let name = args["name"] as? String {
-        return [ "greeting" : "Hello \(name)!" ]
-    } else {
-        return [ "greeting" : "Hello stranger!" ]
-    }
-}
+wsk action update greeting greeting.js
+ok: updated action greeting
 ```
-In this example the Swift action consumes a dictionary and produces a dictionary.
 
-You can create an OpenWhisk action called `helloSwift` from this function as
-follows:
-
-```
-wsk action create helloSwift hello.swift --kind swift:3.1.1
-```
+### Binding parameters to actions
 
-#### Swift 4
+Sometimes it is necessary or just convenient to provide values for function parameters. These can serve as
+defaults, or as a way of reusing an action but with different parameters. Parameters can be bound to an action
+and unless overriden later by an invocation, they will provide the specified value to the function.
 
-New in Swift 4 in addition of the above main function signature there are two more signatures out of the box taking advantage of the [Codable](https://developer.apple.com/documentation/swift/codable) type. You can learn more about data types encodable and decodable for compatibility with external representations such as JSON [here](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types).
+Here is an example.
 
-The following takes as input parameter a Codable Input with field `name`, and returns a Codable output with a field `greetings`
-```swift
-struct Input: Codable {
-    let name: String?
-}
-struct Output: Codable {
-    let greeting: String
-}
-func main(param: Input, completion: (Output?, Error?) -> Void) -> Void {
-    let result = Output(greeting: "Hello \(param.name ?? "stranger")!")
-    print("Log greeting:\(result.greeting)")
-    completion(result, nil)
-}
 ```
-In this example the Swift action consumes a Codable and produces a Codable type.
-If you don't need to handle any input you can use the function signature that doesn't take any input, only Codable output.
-```swift
-struct Output: Codable {
-    let greeting: String
-}
-func main(completion: (Output?, Error?) -> Void) -> Void {
-    let result = Output(greeting: "Hello OpenWhisk!")
-    completion(result, nil)
+wsk action invoke greeting --result
+{
+  "msg": "Hello, stranger from somewhere!"
 }
 ```
-
-
-You can create a OpenWhisk action called `helloSwift` from this function as
-follows:
-
 ```
-wsk action create helloSwift hello.swift --kind swift:4.1
+wsk action update greeting --param name Toto
+ok: updated action greeting
 ```
-
-
-See the Swift [reference](./reference.md#swift-actions) for more information about the Swift runtime.
-
-Action invocation is the same for Swift actions as it is for JavaScript actions:
-
-```
-wsk action invoke --result helloSwift --param name World
-```
-
-```json
-  {
-      "greeting": "Hello World!"
-  }
 ```
-
-Find out more about parameters in the [Working with parameters](./parameters.md) section.
-
-### Packaging an action as a Swift executable
-
-When you create an OpenWhisk Swift action with a Swift source file, it has to be compiled into a binary before the action is run. Once done, subsequent calls to the action are much faster until the container holding your action is purged. This delay is known as the cold-start delay.
-
-To avoid the cold-start delay, you can compile your Swift file into a binary and then upload to OpenWhisk in a zip file. As you need the OpenWhisk scaffolding, the easiest way to create the binary is to build it within the same environment as it will be run in.
-
-### Using a script to build Swift packaged action
-You can use a script to automate the packaging of the action. Create  script `compile.sh`h file the following.
-```bash
-#!/bin/bash
-set -ex
-
-if [ -z "$1" ] ; then
-    echo 'Error: Missing action name'
-    exit 1
-fi
-if [ -z "$2" ] ; then
-    echo 'Error: Missing kind, for example swift:4.1'
-    exit 2
-fi
-OUTPUT_DIR="build"
-if [ ${2} == "swift:3.1.1" ]; then
-  BASE_PATH="/swift3Action"
-  DEST_SOURCE="$BASE_PATH/spm-build"
-  RUNTIME="openwhisk/action-swift-v3.1.1"
-elif [ ${2} == "swift:4.1" ]; then
-  RUNTIME="openwhisk/action-swift-v4.1"
-  BASE_PATH="/swift4Action"
-  DEST_SOURCE="/$BASE_PATH/spm-build/Sources/Action"
-else
-  echo "Error: Kind $2 not recognize"
-  exit 3
-fi
-DEST_PACKAGE_SWIFT="$BASE_PATH/spm-build/Package.swift"
-
-BUILD_FLAGS=""
-if [ -n "$3" ] ; then
-    BUILD_FLAGS=${3}
-fi
-
-echo "Using runtime $RUNTIME to compile swift"
-docker run --rm --name=compile-ow-swift -it -v "$(pwd):/owexec" $RUNTIME bash -ex -c "
-
-if [ -f \"/owexec/$OUTPUT_DIR/$1.zip\" ] ; then
-    rm \"/owexec/$OUTPUT_DIR/$1.zip\"
-fi
-
-echo 'Setting up build...'
-cp /owexec/actions/$1/Sources/*.swift $DEST_SOURCE/
-
-# action file can be either {action name}.swift or main.swift
-if [ -f \"$DEST_SOURCE/$1.swift\" ] ; then
-    echo 'renaming $DEST_SOURCE/$1.swift $DEST_SOURCE/main.swift'
-    mv \"$DEST_SOURCE/$1.swift\" $DEST_SOURCE/main.swift
-fi
-# Add in the OW specific bits
-cat $BASE_PATH/epilogue.swift >> $DEST_SOURCE/main.swift
-echo '_run_main(mainFunction:main)' >> $DEST_SOURCE/main.swift
-
-# Only for Swift4
-if [ ${2} != "swift:3.1.1" ]; then
-  echo 'Adding wait to deal with escaping'
-  echo '_ = _whisk_semaphore.wait(timeout: .distantFuture)' >> $DEST_SOURCE/main.swift
-fi
-
-echo \"Compiling $1...\"
-cd /$BASE_PATH/spm-build
-cp /owexec/actions/$1/Package.swift $DEST_PACKAGE_SWIFT
-# we have our own Package.swift, do a full compile
-swift build ${BUILD_FLAGS} -c release
-
-echo 'Creating archive $1.zip...'
-#.build/release/Action
-mkdir -p /owexec/$OUTPUT_DIR
-zip \"/owexec/$OUTPUT_DIR/$1.zip\" .build/release/Action
-
-"
-```
-
-The script assumes you have a directory `actions` with each top level directory representing an action.
-```
-actions/
-├── hello
-│   ├── Package.swift
-│   └── Sources
-│       └── main.swift
-```
-
-- Create the `Package.swift` file to add dependencies.
-The syntax is different from Swift 3 to Swift 4 tools.
-For Swift 3 here is an example:
-  ```swift
-  import PackageDescription
-
-  let package = Package(
-    name: "Action",
-        dependencies: [
-            .Package(url: "https://github.com/apple/example-package-deckofplayingcards.git", majorVersion: 3),
-            .Package(url: "https://github.com/IBM-Swift/CCurl.git", "0.2.3"),
-            .Package(url: "https://github.com/IBM-Swift/Kitura-net.git", "1.7.10"),
-            .Package(url: "https://github.com/IBM-Swift/SwiftyJSON.git", "15.0.1"),
-            .Package(url: "https://github.com/watson-developer-cloud/swift-sdk.git", "0.16.0")
-        ]
-  )
-  ```
-  For Swift 4 here is an example:
-  ```swift
-  // swift-tools-version:4.0
-  import PackageDescription
-
-  let package = Package(
-      name: "Action",
-      products: [
-        .executable(
-          name: "Action",
-          targets:  ["Action"]
-        )
-      ],
-      dependencies: [
-        .package(url: "https://github.com/apple/example-package-deckofplayingcards.git", .upToNextMajor(from: "3.0.0"))
-      ],
-      targets: [
-        .target(
-          name: "Action",
-          dependencies: ["DeckOfPlayingCards"],
-          path: "."
-        )
-      ]
-  )
-  ```
-  As you can see this example adds `example-package-deckofplayingcards` as a dependency.
-  Notice that `CCurl`, `Kitura-net` and `SwiftyJSON` are provided in the standard Swift action
-and so you should include them in your own `Package.swift` only for Swift 3 actions.
-
-- Build the action by running the following command for a Swift 3 action:
-  ```
-  bash compile.sh hello swift:3.1.1
-  ```
-  To compile for Swift 4 use `swift:4.1` instead of `swift:3.1.1`
-  ```
-  bash compile.sh hello swift:4.1
-  ```
-  This has created hello.zip in the `build`.
-
-- Upload it to OpenWhisk with the action name helloSwifty:
-  For Swift 3 use the kind `swift:3.1.1`
-  ```
-  wsk action update helloSwiftly build/hello.zip --kind swift:3.1.1
-  ```
-  For Swift 4 use the kind `swift:3.1.1`
-  ```
-  wsk action update helloSwiftly build/hello.zip --kind swift:4.1
-  ```
-
-- To check how much faster it is, run
-  ```
-  wsk action invoke helloSwiftly --blocking
-  ```
-
-  The time it took for the action to run is in the "duration" property and compare to the time it takes to run with a compilation step in the hello action.
-
-### Error Handling in Swift 4
-
-With the new Codable completion handler, you can pass an Error to indicate a failure in your Action.
-[Error handling in Swift](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html) resembles exception handling in other languages, with the use of the `try, catch` and `throw` keywords.
-The following example shows a an example on handling an error
-```swift
-enum VendingMachineError: Error {
-    case invalidSelection
-    case insufficientFunds(coinsNeeded: Int)
-    case outOfStock
-}
-func main(param: Input, completion: (Output?, Error?) -> Void) -> Void {
-    // Return real error
-    do{
-        throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
-    } catch {
-        completion(nil, error)
-    }
+wsk action invoke greeting --result
+{
+  "msg": "Hello, Toto from somewhere!"
 }
 ```
 
-
-
-## Creating Java actions
-
-The process of creating Java actions is similar to that of JavaScript and Swift actions. The following sections guide you through creating and invoking a single Java action, and adding parameters to that action.
-
-In order to compile, test and archive Java files, you must have a [JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) installed locally.
-
-### Creating and invoking an action
-
-A Java action is a Java program with a method called `main` that has the exact signature as follows:
-```java
-public static com.google.gson.JsonObject main(com.google.gson.JsonObject);
+You may still provide additional parmaeters, as in the `place`:
 ```
-
-For example, create a Java file called `Hello.java` with the following content:
-
-```java
-import com.google.gson.JsonObject;
-
-public class Hello {
-    public static JsonObject main(JsonObject args) {
-        String name = "stranger";
-        if (args.has("name"))
-            name = args.getAsJsonPrimitive("name").getAsString();
-        JsonObject response = new JsonObject();
-        response.addProperty("greeting", "Hello " + name + "!");
-        return response;
-    }
+wsk action invoke greeting --result --param place Kansas
+{
+  "msg": "Hello, Toto from Kansas!"
 }
 ```
-
-Then, compile `Hello.java` into a JAR file `hello.jar` as follows:
-```
-javac Hello.java
-```
-```
-jar cvf hello.jar Hello.class
-```
-
-**Note:** [google-gson](https://github.com/google/gson) must exist in your Java CLASSPATH when compiling the Java file.
-
-You can create a OpenWhisk action called `helloJava` from this JAR file as
-follows:
-
-```
-wsk action create helloJava hello.jar --main Hello
-```
-
-When you use the command line and a `.jar` source file, you do not need to
-specify that you are creating a Java action;
-the tool determines that from the file extension.
-
-You need to specify the name of the main class using `--main`. An eligible main
-class is one that implements a static `main` method as described above. If the
-class is not in the default package, use the Java fully-qualified class name,
-e.g., `--main com.example.MyMain`.
-
-If needed you can also customize the method name of your Java action. This
-can be done by specifying the Java fully-qualified method name of your action,
-e.q., `--main com.example.MyMain#methodName`
-
-Action invocation is the same for Java actions as it is for Swift and JavaScript actions:
-
+and even override the `name`:
 ```
-wsk action invoke --result helloJava --param name World
-```
-
-```json
-  {
-      "greeting": "Hello World!"
-  }
+wsk action invoke greeting --result --param place Kansas --param name Dorothy
+{
+  "msg": "Hello, Dorothy from Kansas!"
+}
 ```
 
-Find out more about parameters in the [Working with parameters](./parameters.md) section.
-
-## Creating Docker actions
+### Action execution
+
+When an invocation request is received, the system records the request and dispatches an activation.
+
+The system returns an activation ID (in the case of a nonblocking invocation) to confirm that the invocation was received.
+Notice that if there's a network failure or other failure which intervenes before you receive an HTTP response, it is possible
+that OpenWhisk received and processed the request.
+
+The system attempts to invoke the action once and records the `status` in the [activation record](#understanding-the-activation-record).
+Every invocation that is successfully received, and that the user might be billed for, will eventually have an activation record.
+
+Note that in the case of [*action developer error*](#understanding-the-activation-record), the action may
+have partially run and generated externally visible side effects. It is the user's responsibility to check
+whether such side effects actually happened, and issue retry logic if desired.
+Also note that certain [*whisk internal errors*](#understanding-the-activation-record) will indicate that
+an action started running but the system failed before the action registered completion.
+
+### Further considerations
+- Functions should be stateless, or *idempotent*. While the system does not enforce this property,
+there is no guarantee that any state maintained by an action will be available across invocations. In some cases,
+deliberately leaking state across invocations may be advantageous for performance, but also exposes some risks.
+- An action executes in a sandboxed environment, namely a container. At any given time, a single activation will
+execute inside the container. Subsequent invocations of the same action may reuse a previous container,
+and there may exist more than one container at any given time, each having its own state.
+- Invocations of an action are not ordered. If the user invokes an action twice from the command line or the REST API,
+the second invocation might run before the first. If the actions have side effects, they might be observed in any order.
+- There is no guarantee that actions will execute atomically. Two actions can run concurrently and their side effects
+can be interleaved. OpenWhisk does not ensure any particular concurrent consistency model for side effects.
+Any concurrency side effects will be implementation-dependent.
+- Actions have two phases: an initialization phase, and a run phase. During initialization, the function is loaded
+and prepared for execution. The run phase receives the action parameters provided at invocation time. Initialization
+is skipped if an action is dispatched to a previously initialized container --- this is referred to as a _warm start_.
+You can tell if an [invocation was a warm activation or a cold one requiring initialization](annotations.md#annotations-specific-to-activations)
+by inspecting the activation record.
+- An action runs for a bounded amount of time. This limit can be configured per action, and applies to both the
+initialization and the execution separately.
+- Functions should follow best practices to reduce [vulnerabilities](security.md) by treating input as untrusted,
+and be aware of vulnerabilities they may inherit from third-party dependencies.
 
-With OpenWhisk Docker actions, you can write your actions in any language.
-
-Your code is compiled into an executable binary and embedded into a Docker image. The binary program interacts with the system by taking input from `stdin` and replying through `stdout`.
-
-As a prerequisite, you must have a Docker Hub account.  To set up a free Docker ID and account, go to [Docker Hub](https://hub.docker.com).
+## Creating action sequences
 
-For the instructions that follow, assume that the Docker user ID is `janesmith` and the password is `janes_password`.  Assuming that the CLI is already set up, three steps are required to set up a custom binary for use by OpenWhisk. After that, the uploaded Docker image can be used as an action.
+A powerful feature of the OpenWhisk programming model is the ability to compose actions together. A common
+composition is a sequence of actions, where the result of one action becomes the input to the next action in
+the sequence.
 
-1. Download the Docker skeleton. You can download it by using the CLI as follows:
+Here we will use several utility actions that are provided in the `/whisk.system/utils`
+[package](packages.md) to create your first sequence.
 
-  ```
-  wsk sdk install docker
-  ```
-  ```
-  The Docker skeleton is now installed at the current directory.
-  ```
+1. Display the actions in the `/whisk.system/utils` package.
 
   ```
-  $ ls dockerSkeleton/
-  ```
-  ```
-  Dockerfile      README.md       buildAndPush.sh example.c
-  ```
-
-  The skeleton is a Docker container template where you can inject your code in the form of custom binaries.
-
-2. Set up your custom binary in the blackbox skeleton. The skeleton already includes a C program that you can use.
-
+  wsk package get --summary /whisk.system/utils
   ```
-  cat dockerSkeleton/example.c
   ```
-  ```c
-  #include <stdio.h>
-  int main(int argc, char *argv[]) {
-      printf("This is an example log message from an arbitrary C program!\n");
-      printf("{ \"msg\": \"Hello from arbitrary C program!\", \"args\": %s }",
-             (argc == 1) ? "undefined" : argv[1]);
-  }
+  package /whisk.system/utils: Building blocks that format and assemble data
+     (parameters: none defined)
+   action /whisk.system/utils/split: Split a string into an array
+     (parameters: payload, separator)
+   action /whisk.system/utils/sort: Sorts an array
+     (parameters: lines)
+   ...
   ```
 
-  You can modify this file as needed, or, add additional code and dependencies to the Docker image.
-  In case of the latter, you may need to tweak the `Dockerfile` as necessary to build your executable.
-  The binary must be located inside the container at `/action/exec`.
+  You will be using the `split` and `sort` actions in this example shown here, although the package contains more actions.
 
-  The executable receives a single argument from the command line. It is a string serialization of the JSON
-  object representing the arguments to the action. The program may log to `stdout` or `stderr`.
-  By convention, the last line of output _must_ be a stringified JSON object which represents the result of the action.
-
-3. Build the Docker image and upload it using a supplied script. You must first run `docker login` to authenticate, and then run the script with a chosen image name.
+2. Create an action sequence so that the result of one action is passed as an argument to the next action.
 
   ```
-  docker login -u janesmith -p janes_password
-  ```
-  ```
-  cd dockerSkeleton
-  ```
+  wsk action create mySequence --sequence /whisk.system/utils/split,/whisk.system/utils/sort
   ```
-  ./buildAndPush.sh janesmith/blackboxdemo
-  ```
-
-  Notice that part of the example.c file is compiled as part of the Docker image build process, so you do not need C compiled on your machine.
-  In fact, unless you are compiling the binary on a compatible host machine, it may not run inside the container since formats will not match.
-
-  Your Docker container may now be used as an OpenWhisk action.
-
 
-  ```
-  wsk action create example --docker janesmith/blackboxdemo
-  ```
+  This action sequence converts some lines of text to an array, and sorts the lines.
 
-  Notice the use of `--docker` when creating an action. Currently all Docker images are assumed to be hosted on Docker Hub.
-  The action may be invoked as any other OpenWhisk action.
+3. Invoke the action:
 
   ```
-  wsk action invoke --result example --param payload Rey
+  wsk action invoke --result mySequence --param payload "Over-ripe sushi,\nThe Master\nIs full of regret."
   ```
   ```json
   {
-      "args": {
-          "payload": "Rey"
-      },
-      "msg": "Hello from arbitrary C program!"
+      "length": 3,
+      "lines": [
+          "Is full of regret.",
+          "Over-ripe sushi,",
+          "The Master"
+      ]
   }
   ```
 
-  To update the Docker action, run buildAndPush.sh to upload the latest image to Docker Hub. This will allow the system to pull your new Docker image the next time it runs the code for your action.
-  If there are no warm containers any new invocations will use the new Docker image.
-  However, if there is a warm container using a previous version of your Docker image, any new invocations will continue to use that image unless you run `wsk action update`. This will indicate to the system that for new invocations it should execute a docker pull to get your new Docker image.
-
-  ```
-  ./buildAndPush.sh janesmith/blackboxdemo
-  ```
-  ```
-  wsk action update example --docker janesmith/blackboxdemo
-  ```
-
-  You can find more information about creating Docker actions in the [References](./reference.md#docker-actions) section.
-
-  *Note:* Previous version of the CLI supported `--docker` without a parameter and the image name was a positional argument.
-  In order to allow Docker actions to accept initialization data via a (zip) file, similar to other actions kinds, we have
-  normalized the user experience for Docker actions so that a positional argument if present must be a file (e.g., a zip file)
-  instead. The image name must be specified following the `--docker` option. Furthermore, due to user feedback, we have added
-  `--native` as shorthand for `--docker openwhisk/dockerskeleton` so that executables that run inside the standard Docker action
-  SDK are more convenient to create and deploy.
-
-  For example, the tutorial above created a binary executable inside the container locate at `/action/exec`. If you copy this file
-  to your local file system and zip it into `exec.zip` then you can use the following commands to create a docker action which receives
-  the executable as initialization data.
-
-  ```bash
-  wsk action create example exec.zip --native
-  ```
-  which is equivalent to the following command.
-  ```bash
-  wsk action create example exec.zip --docker openwhisk/dockerskeleton
-  ```
-
-## Creating Go actions
-
-The `--native` option allows for packaging of any executable as an action. This works for Go as an example.
-As with Docker actions, the Go executable receives a single argument from the command line.
-It is a string serialization of the JSON object representing the arguments to the action.
-The program may log to `stdout` or `stderr`.
-By convention, the last line of output _must_ be a stringified JSON object which represents the result of the action.
-
-Here is an example Go action.
-```go
-package main
-
-import "encoding/json"
-import "fmt"
-import "os"
-
-func main() {
-    //program receives one argument: the JSON object as a string
-    arg := os.Args[1]
-
-    // unmarshal the string to a JSON object
-    var obj map[string]interface{}
-    json.Unmarshal([]byte(arg), &obj)
-
-    // can optionally log to stdout (or stderr)
-    fmt.Println("hello Go action")
-
-    name, ok := obj["name"].(string)
-    if !ok { name = "Stranger" }
-
-    // last line of stdout is the result JSON object as a string
-    msg := map[string]string{"msg": ("Hello, " + name + "!")}
-    res, _ := json.Marshal(msg)
-    fmt.Println(string(res))
-}
-```
-
-Save the code above to a file `sample.go` and cross compile it for OpenWhisk. The executable must be called `exec`.
-```bash
-GOOS=linux GOARCH=amd64 go build -o exec
-zip exec.zip exec
-wsk action create helloGo --native exec.zip
-```
-
-The action may be run as any other action.
-```bash
-wsk action invoke helloGo -r -p name gopher
-{
-    "msg": "Hello, gopher!"
-}
-```
-
-Find out more about parameters in the [Working with parameters](./parameters.md) section.
-
-Logs are retrieved in a similar way as well.
-
-```bash
-wsk activation logs --last --strip
-my first Go action.
-```
+  In the result, you see that the lines are sorted.
 
-## Creating native actions
+**Note**: Parameters passed between actions in the sequence are explicit, except for default parameters.
+Therefore parameters that are passed to the sequence action (e.g., `mySequence`) are only available to the first action in the sequence.
+The result of the first action in the sequence becomes the input JSON object to the second action in the sequence (and so on).
+This object does not include any of the parameters originally passed to the sequence unless the first action explicitly includes them in its result.
+Input parameters to an action are merged with the action's default parameters, with the former taking precedence and overriding any matching default parameters.
+For more information about invoking action sequences with multiple named parameters, learn about [setting default parameters](parameters.md#setting-default-parameters).
 
-Using `--native`, you can see that any executable may be run as an OpenWhisk action. This includes `bash` scripts,
-or cross compiled binaries. For the latter, the constraint is that the binary must be compatible with the
-`openwhisk/dockerskeleton` image.
+A more advanced form of composition using *conductor* actions is described [here](conductors.md).
 
 ## Watching action output
 
@@ -1201,29 +406,27 @@ OpenWhisk actions might be invoked by other users, in response to various events
 You can use the OpenWhisk CLI to watch the output of actions as they are invoked.
 
 1. Issue the following command from a shell:
-  ```
-  wsk activation poll
-  ```
+```
+wsk activation poll
+```
 
 This command starts a polling loop that continuously checks for logs from activations.
 
 2. Switch to another window and invoke an action:
 
-  ```
-  wsk action invoke /whisk.system/samples/helloWorld --param payload Bob
-  ```
-  ```
-  ok: invoked /whisk.system/samples/helloWorld with id 7331f9b9e2044d85afd219b12c0f1491
-  ```
+```
+wsk action invoke /whisk.system/samples/helloWorld --param payload Bob
+ok: invoked /whisk.system/samples/helloWorld with id 7331f9b9e2044d85afd219b12c0f1491
+```
 
 3. Observe the activation log in the polling window:
 
-  ```
-  Activation: helloWorld (7331f9b9e2044d85afd219b12c0f1491)
-    2016-02-11T16:46:56.842065025Z stdout: hello bob!
-  ```
+```
+Activation: helloWorld (7331f9b9e2044d85afd219b12c0f1491)
+  2016-02-11T16:46:56.842065025Z stdout: hello bob!
+```
 
-  Similarly, whenever you run the poll utility, you see in real time the logs for any actions running on your behalf in OpenWhisk.
+Similarly, whenever you run the poll utility, you see in real time the logs for any actions running on your behalf in OpenWhisk.
 
 ## Getting actions
 
@@ -1233,7 +436,7 @@ Metadata that describes existing actions can be retrieved via the `wsk action ge
 wsk action get hello
 ok: got action hello
 {
-    "namespace": "user@email.com",
+    "namespace": "guest",
     "name": "hello",
     "version": "0.0.1",
     "exec": {
@@ -1255,29 +458,49 @@ ok: got action hello
 }
 ```
 
-### Getting an action URL
+### Getting the URL for an action
 
-An action can be invoked through the REST interface via an HTTPS request. To get an action URL, execute the following command:
+An action can be invoked through the REST interface via an HTTPS request.
+To get an action URL, execute the following command:
 
 ```
-wsk action get actionName --url
+wsk action get greeting --url
 ```
 
 A URL with the following format will be returned for standard actions:
 ```
 ok: got action actionName
-https://${APIHOST}/api/v1/namespaces/${NAMESPACE}/actions/actionName
+https://${APIHOST}/api/v1/namespaces/${NAMESPACE}/actions/greeting
 ```
 
-For [web actions](https://github.com/apache/incubator-openwhisk/blob/master/docs/webactions.md#web-actions), a URL will be returned in the the following format:
+Authentication is required when invoking an action via an HTTPS request using this resource path.
+For more information regarding action invocations using the REST interface, see [Using REST APIs with OpenWhisk](rest_api.md#actions).
+
+Another way of invoking an action which does not require authentication is via
+[web actions](webactions.md#web-actions).
+
+Any action may be exposed as a web action, using the `--web true` command line option at action
+creation time (or later when updating the action).
+
 ```
-ok: got action actionName
-https://${APIHOST}/api/v1/web/${NAMESPACE}/${PACKAGE}/actionName
+wsk action update greeting --web true
+ok: updated action greeting
+```
+
+The resource URL for a web action is different:
+```
+wsk action get greeting --url
+ok: got action greeting
+https://${APIHOST}/api/v1/web/${NAMESPACE}/${PACKAGE}/greeting
 ```
 
-**Note:** For standard actions, authentication must be provided when invoking an action via an HTTPS request. For more information regarding
-action invocations using the REST interface, see
-[Using REST APIs with OpenWhisk](rest_api.md#actions).
+You can use `curl` or wget to invoke the action.
+```
+curl `wsk action get greeting --url | tail -1`.json
+{
+  "payload": "Hello, Toto from somewhere!"
+}
+```
 
 ### Saving action code
 
@@ -1285,18 +508,14 @@ Code associated with an existing action may be retrieved and saved locally. Savi
 
 1. Save action code to a filename that corresponds with an existing action name in the current working directory. A file extension that corresponds to the action kind is used, or an extension of `.zip` will be used for action code that is a zip file.
   ```
-  wsk action get actionName --save
-  ```
-  ```
-  ok: saved action code to /absolutePath/currentDirectory/actionName.js
+  wsk action get /whisk.system/samples/greeting --save
+  ok: saved action code to /path/to/openwhisk/greeting.js
   ```
 
-2. Instead of allowing the CLI to determine the destination of the code to be saved, a custom file path, filename and extension can be provided by using the `--save-as` flag.
-  ```
-  wsk action get actionName --save-as codeFile.js
+2. You may provide your own file name and extension as well using the `--save-as` flag.
   ```
-  ```
-  ok: saved action code to /absolutePath/currentDirectory/codeFile.js
+  wsk action get /whisk.system/samples/greeting --save-as hello.js
+  ok: saved action code to /path/to/openwhisk/hello.js
   ```
 
 ## Listing actions
@@ -1305,38 +524,45 @@ You can list all the actions that you have created using `wsk action list`:
 
 ```
 wsk action list
+```
+```
 actions
-/guest/packageB/A                  private nodejs:6
-/guest/C                           private nodejs:6
-/guest/A                           private nodejs:6
-/guest/packageA/B                  private nodejs:6
-/guest/packageA/A                  private nodejs:6
-/guest/B                           private nodejs:6
+/guest/mySequence                  private sequence
+/guest/greeting                    private nodejs:6
 ```
 
 Here, we see actions listed in order from most to least recently updated. For easier browsing, you can use the flag `--name-sort` or `-n` to sort the list alphabetically:
 
 ```
 wsk action list --name-sort
+```
+```
 actions
-/guest/A                           private nodejs:6
-/guest/B                           private nodejs:6
-/guest/C                           private nodejs:6
-/guest/packageA/A                  private nodejs:6
-/guest/packageA/B                  private nodejs:6
-/guest/packageB/A                  private nodejs:6
+/guest/mySequence                  private sequence
+/guest/greeting                    private nodejs:6
 ```
 
-Notice that the list is now sorted alphabetically by namespace, then package name, and finally action name, with the default package (no specified package) listed at the top.
+Notice that the list is now sorted alphabetically by namespace, then package name if any, and finally action name, with the default package (no specified package) listed at the top.
 
-**Note**: The printed list is sorted alphabetically after it is received from the server. Other list flags such as `--limit` and `--skip` will be applied to the block of actions before they are received for sorting. To list actions in order by creation time, use the flag `--time`.
+**Note**: The printed list is sorted alphabetically after it is received from the platform. Other list flags such as `--limit` and `--skip` will be applied to the block of actions before they are received for sorting. To list actions in order by creation time, use the flag `--time`.
 
-As you write more actions, this list gets longer and it can be helpful to group related actions into [packages](./packages.md). To filter your list of actions to just those within a specific package, you can use:
+As you write more actions, this list gets longer and it can be helpful to group related actions into [packages](packages.md). To filter your list of actions to just those within a specific package, you can use:
 
 ```
-wsk action list [PACKAGE NAME]
+wsk action list action list /whisk.system/utils
+```
+```
+actions
+/whisk.system/utils/hosturl        private nodejs:6
+/whisk.system/utils/namespace      private nodejs:6
+/whisk.system/utils/cat            private nodejs:6
+/whisk.system/utils/smash          private nodejs:6
+/whisk.system/utils/echo           private nodejs:6
+/whisk.system/utils/split          private nodejs:6
+/whisk.system/utils/date           private nodejs:6
+/whisk.system/utils/head           private nodejs:6
+/whisk.system/utils/sort           private nodejs:6
 ```
-
 
 ## Deleting actions
 
@@ -1344,10 +570,8 @@ You can clean up by deleting actions that you do not want to use.
 
 1. Run the following command to delete an action:
   ```
-  wsk action delete hello
-  ```
-  ```
-  ok: deleted hello
+  wsk action delete greeting
+  ok: deleted greeting
   ```
 
 2. Verify that the action no longer appears in the list of actions.
@@ -1356,6 +580,7 @@ You can clean up by deleting actions that you do not want to use.
   ```
   ```
   actions
+  /guest/mySequence                private sequence
   ```
 
 ## Accessing action metadata within the action body
diff --git a/docs/reference.md b/docs/reference.md
index d954c291a9..7feaa6f8f6 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -64,390 +64,6 @@ The names of all entities, including actions, triggers, rules, packages, and nam
 
 More precisely, a name must match the following regular expression (expressed with Java metacharacter syntax): `\A([\w]|[\w][\w@ .-]*[\w@.-]+)\z`.
 
-
-## Action semantics
-
-The following sections describe details about OpenWhisk actions.
-
-### Statelessness
-
-Action implementations should be stateless, or *idempotent*. While the system does not enforce this property, there is no guarantee that any state maintained by an action will be available across invocations.
-
-Moreover, multiple instantiations of an action might exist, with each instantiation having its own state. An action invocation might be dispatched to any of these instantiations.
-
-### Invocation input and output
-
-The input to and output from an action is a dictionary of key-value pairs. The key is a string, and the value a valid JSON value.
-
-### Invocation ordering of actions
-
-Invocations of an action are not ordered. If the user invokes an action twice from the command line or the REST API, the second invocation might run before the first. If the actions have side effects, they might be observed in any order.
-
-Additionally, there is no guarantee that actions will execute atomically. Two actions can run concurrently and their side effects can be interleaved. OpenWhisk does not ensure any particular concurrent consistency model for side effects. Any concurrency side effects will be implementation-dependent.
-
-### Action execution guarantees
-
-When an invocation request is received, the system records the request and dispatches an activation.
-
-The system returns an activation ID (in the case of a nonblocking invocation) to confirm that the invocation was received.
-Notice that if there's a network failure or other failure which intervenes before you receive an HTTP response, it is possible
-that OpenWhisk received and processed the request.
-
-The system attempts to invoke the action once, resulting in one of the following four outcomes:
-- *success*: the action invocation completed successfully.
-- *application error*: the action invocation was successful, but the action returned an error value on purpose, for instance because a precondition on the arguments was not met.
-- *action developer error*: the action was invoked, but it completed abnormally, for instance the action did not detect an exception, or a syntax error existed.
-- *whisk internal error*: the system was unable to invoke the action.
-The outcome is recorded in the `status` field of the activation record, as document in a following section.
-
-Every invocation that is successfully received, and that the user might be billed for, will eventually have an activation record.
-
-Note that in the case of *action developer error*, the action may have partially run and generated externally visible
-side effects.   It is the user's responsibility to check whether such side effects actually happened, and issue retry
-logic if desired.   Also note that certain *whisk internal errors* will indicate that an action started running but the
-system failed before the action registered completion.
-
-## Activation record
-
-Each action invocation and trigger firing results in an activation record.
-
-An activation record contains the following fields:
-
-- *activationId*: The activation ID.
-- *start* and *end*: Timestamps recording the start and end of the activation. The values are in [UNIX time format](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15).
-- *namespace* and `name`: The namespace and name of the entity.
-- *logs*: An array of strings with the logs that are produced by the action during its activation. Each array element corresponds to a line output to `stdout` or `stderr` by the action, and includes the time and stream of the log output. The structure is as follows: `TIMESTAMP STREAM: LOG_OUTPUT`.
-- *response*: A dictionary that defines the keys `success`, `status`, and `result`:
-  - *status*: The activation result, which might be one of the following values: "success", "application error", "action developer error", "whisk internal error".
-  - *success*: Is `true` if and only if the status is `"success"`
-- *result*: A dictionary that contains the activation result. If the activation was successful, this contains the value that is returned by the action. If the activation was unsuccessful, `result` contains the `error` key, generally with an explanation of the failure.
-
-
-## JavaScript actions
-
-### Function prototype
-
-OpenWhisk JavaScript actions run in a Node.js runtime.
-
-Actions written in JavaScript must be confined to a single file. The file can contain multiple functions but by convention a function called `main` must exist and is the one called when the action is invoked. For example, the following is an example of an action with multiple functions.
-
-```javascript
-function main() {
-    return { payload: helper() }
-}
-function helper() {
-    return new Date();
-}
-```
-
-The action input parameters are passed as a JSON object as a parameter to the `main` function. The result of a successful activation is also a JSON object but is returned differently depending on whether the action is synchronous or asynchronous as described in the following section.
-
-
-### Synchronous and asynchronous behavior
-
-It is common for JavaScript functions to continue execution in a callback function even after a return. To accommodate this, an activation of a JavaScript action can be *synchronous* or *asynchronous*.
-
-A JavaScript action's activation is **synchronous** if the main function exits under one of the following conditions:
-
-- The main function exits without executing a `return` statement.
-- The main function exits by executing a `return` statement that returns any value *except* a Promise.
-
-Here is an example of a synchronous action.
-
-```javascript
-// an action in which each path results in a synchronous activation
-function main(params) {
-  if (params.payload == 0) {
-     return {};
-  } else if (params.payload == 1) {
-     return {payload: 'Hello, World!'};
-  } else if (params.payload == 2) {
-    return {error: 'payload must be 0 or 1'};
-  }
-}
-```
-
-A JavaScript action's activation is **asynchronous** if the main function exits by returning a Promise.  In this case, the system assumes that the action is still running, until the Promise has been fulfilled or rejected.
-Start by instantiating a new Promise object and passing it a callback function. The callback takes two arguments, resolve and reject, which are both functions. All your asynchronous code goes inside that callback.
-
-
-The following is an example on how to fulfill a Promise by calling the resolve function.
-
-```javascript
-function main(args) {
-     return new Promise(function(resolve, reject) {
-       setTimeout(function() {
-         resolve({ done: true });
-       }, 100);
-    })
- }
-```
-
-The following is an example on how to reject a Promise by calling the reject function.
-
-```javascript
-function main(args) {
-     return new Promise(function(resolve, reject) {
-       setTimeout(function() {
-         reject({ done: true });
-       }, 100);
-    })
- }
-```
-
-It is possible for an action to be synchronous on some inputs and asynchronous on others. The following is an example.
-
-```javascript
-  function main(params) {
-      if (params.payload) {
-         // asynchronous activation
-         return new Promise(function(resolve, reject) {
-                setTimeout(function() {
-                  resolve({ done: true });
-                }, 100);
-             })
-      }  else {
-         // synchronous activation
-         return {done: true};
-      }
-  }
-```
-
-Notice that regardless of whether an activation is synchronous or asynchronous, the invocation of the action can be blocking or non-blocking.
-
-### JavaScript global whisk object removed
-
-The global object `whisk` has been removed; migrate your nodejs actions to use alternative methods.
-For the functions `whisk.invoke()` and `whisk.trigger()` use the already installed client library [openwhisk](https://www.npmjs.com/package/openwhisk).
-For the `whisk.getAuthKey()` you can get the API key value from the environment variable `__OW_API_KEY`.
-For the `whisk.error()` you can return a rejected Promise (i.e. Promise.reject).
-
-### JavaScript runtime environments
-
-JavaScript actions can be executed in Node.js version 6 or Node.js version 8.
-Currently actions are executed by default in a Node.js version 6 environment.
-
-### Node.js version 6 environment
-The Node.js 6.14.2 environment will be used for an action if the `--kind` flag is explicitly specified with a value of 'nodejs:6' when creating/updating the action.
-
-The following packages are available to be used in the Node.js 6.14.2 environment:
-
-- [apn v2.1.2](https://www.npmjs.com/package/apn) - A Node.js module for interfacing with the Apple Push Notification service.
-- [async v2.1.4](https://www.npmjs.com/package/async) - Provides functions for working with asynchronous functions.
-- [btoa v1.1.2](https://www.npmjs.com/package/btoa) - A port of the browser's btoa function.
-- [cheerio v0.22.0](https://www.npmjs.com/package/cheerio) - Fast, flexible & lean implementation of core jQuery designed specifically for the server.
-- [cloudant v1.6.2](https://www.npmjs.com/package/cloudant) - This is the official Cloudant library for Node.js.
-- [commander v2.9.0](https://www.npmjs.com/package/commander) - The complete solution for Node.js command-line interfaces.
-- [consul v0.27.0](https://www.npmjs.com/package/consul) - A client for Consul, involving service discovery and configuration.
-- [cookie-parser v1.4.3](https://www.npmjs.com/package/cookie-parser) - Parse Cookie header and populate req.cookies with an object keyed by the cookie names.
-- [cradle v0.7.1](https://www.npmjs.com/package/cradle) - A high-level, caching, CouchDB client for Node.js.
-- [errorhandler v1.5.0](https://www.npmjs.com/package/errorhandler) - Development-only error handler middleware.
-- [glob v7.1.1](https://www.npmjs.com/package/glob) - Match files by using patterns that the shell uses, like stars and stuff.
-- [gm v1.23.0](https://www.npmjs.com/package/gm) - GraphicsMagick and ImageMagick for Node.
-- [lodash v4.17.2](https://www.npmjs.com/package/lodash) - The Lodash library exported as Node.js modules.
-- [log4js v0.6.38](https://www.npmjs.com/package/log4js) - A conversion of the log4js framework designed to work with Node.
-- [iconv-lite v0.4.15](https://www.npmjs.com/package/iconv-lite) - Pure JS character encoding conversion
-- [marked v0.3.6](https://www.npmjs.com/package/marked) - A full-featured markdown parser and compiler, which is written in JavaScript. Built for speed.
-- [merge v1.2.0](https://www.npmjs.com/package/merge) - Merge multiple objects into one, optionally creating a new cloned object.
-- [moment v2.17.0](https://www.npmjs.com/package/moment) - A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
-- [mongodb v2.2.11](https://www.npmjs.com/package/mongodb) - The official MongoDB driver for Node.js.
-- [mustache v2.3.0](https://www.npmjs.com/package/mustache) - Mustache.js is an implementation of the mustache template system in JavaScript.
-- [nano v6.2.0](https://www.npmjs.com/package/nano) - Minimalistic couchdb driver for Node.js.
-- [node-uuid v1.4.7](https://www.npmjs.com/package/node-uuid) - Deprecated UUID packaged.
-- [nodemailer v2.6.4](https://www.npmjs.com/package/nodemailer) - Send e-mails from Node.js – easy as cake!
-- [oauth2-server v2.4.1](https://www.npmjs.com/package/oauth2-server) - Complete, compliant, and well tested module for implementing an OAuth2 Server/Provider with express in Node.js.
-- [openwhisk v3.15.0](https://www.npmjs.com/package/openwhisk) - JavaScript client library for the OpenWhisk platform. Provides a wrapper around the OpenWhisk APIs.
-- [pkgcloud v1.4.0](https://www.npmjs.com/package/pkgcloud) - pkgcloud is a standard library for Node.js that abstracts away differences among multiple cloud providers.
-- [process v0.11.9](https://www.npmjs.com/package/process) - Require('process'); just like any other module.
-- [pug v2.0.0-beta6](https://www.npmjs.com/package/pug) - Implements the Pug templating language.
-- [redis v2.6.3](https://www.npmjs.com/package/redis) - This is a complete and feature-rich Redis client for Node.js.
-- [request v2.79.0](https://www.npmjs.com/package/request) - Request is the simplest way possible to make HTTP calls.
-- [request-promise v4.1.1](https://www.npmjs.com/package/request-promise) - The simplified HTTP request client 'request' with Promise support. Powered by Bluebird.
-- [rimraf v2.5.4](https://www.npmjs.com/package/rimraf) - The UNIX command rm -rf for node.
-- [semver v5.3.0](https://www.npmjs.com/package/semver) - Supports semantic versioning.
-- [sendgrid v4.7.1](https://www.npmjs.com/package/sendgrid) - Provides email support via the SendGrid API.
-- [serve-favicon v2.3.2](https://www.npmjs.com/package/serve-favicon) - Node.js middleware for serving a favicon.
-- [socket.io v1.6.0](https://www.npmjs.com/package/socket.io) - Socket.IO enables real-time bidirectional event-based communication.
-- [socket.io-client v1.6.0](https://www.npmjs.com/package/socket.io-client) - Client-side support for Socket.IO.
-- [superagent v3.0.0](https://www.npmjs.com/package/superagent) - SuperAgent is a small progressive client-side HTTP request library, and Node.js module with the same API, sporting many high-level HTTP client features.
-- [swagger-tools v0.10.1](https://www.npmjs.com/package/swagger-tools) - Tools that are related to working with Swagger, a way to document APIs.
-- [tmp v0.0.31](https://www.npmjs.com/package/tmp) - A simple temporary file and directory creator for node.js.
-- [twilio v2.11.1](https://www.npmjs.com/package/twilio) - A wrapper for the Twilio API, related to voice, video, and messaging.
-- [underscore v1.8.3](https://www.npmjs.com/package/underscore) - Underscore.js is a utility-belt library for JavaScript that supports the usual functional suspects (each, map, reduce, filter...) without extending any core JavaScript objects.
-- [uuid v3.0.0](https://www.npmjs.com/package/uuid) - Simple, fast generation of RFC4122 UUIDS.
-- [validator v6.1.0](https://www.npmjs.com/package/validator) - A library of string validators and sanitizers.
-- [watson-developer-cloud v2.29.0](https://www.npmjs.com/package/watson-developer-cloud) - Node.js client library to use the Watson Developer Cloud services, a collection of APIs that use cognitive computing to solve complex problems.
-- [when v3.7.7](https://www.npmjs.com/package/when) - When.js is a rock solid, battle-tested Promises/A+ and when() implementation, including a complete ES6 Promise shim.
-- [winston v2.3.0](https://www.npmjs.com/package/winston) - A multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs."
-- [ws v1.1.1](https://www.npmjs.com/package/ws) - ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and server implementation.
-- [xml2js v0.4.17](https://www.npmjs.com/package/xml2js) - Simple XML to JavaScript object converter. It supports bi-directional conversion.
-- [xmlhttprequest v1.8.0](https://www.npmjs.com/package/xmlhttprequest) - node-XMLHttpRequest is a wrapper for the built-in http client to emulate the browser XMLHttpRequest object.
-- [yauzl v2.7.0](https://www.npmjs.com/package/yauzl) - Yet another unzip library for node. For zipping.
-
-### Node.js version 8 environment
-The Node.js version 8.11.2 environment is used if the `--kind` flag is explicitly specified with a value of 'nodejs:8' when creating or updating an Action.
-
-The following packages are pre-installed in the Node.js version 8.11.2 environment:
-
-- [openwhisk v3.15.0](https://www.npmjs.com/package/openwhisk) - JavaScript client library for the OpenWhisk platform. Provides a wrapper around the OpenWhisk APIs.
-
-### Packaging npm packages with your actions
-For any `npm` packages that are not pre-installed in the Node.js environment, you can bundle them as dependencies when you create or update your action.
-
-For more information, see [Packaging an action as a Node.js module](./actions.md#packaging-an-action-as-a-nodejs-module) or [Packaging an action as a single bundle](./actions.md#packaging-an-action-as-a-single-bundle).
-
-## Python actions
-OpenWhisk supports running Python actions using two different runtime versions.
-
-### Python 3 actions
-
-Python 3 actions are executed using Python 3.6.1. To use this runtime, specify the `wsk` CLI parameter `--kind python:3` when creating or updating an action.
-The following packages are available for use by Python actions, in addition to the Python 3.6 standard libraries.
-
-- aiohttp v1.3.3
-- appdirs v1.4.3
-- asn1crypto v0.21.1
-- async-timeout v1.2.0
-- attrs v16.3.0
-- beautifulsoup4 v4.5.1
-- cffi v1.9.1
-- chardet v2.3.0
-- click v6.7
-- cryptography v1.8.1
-- cssselect v1.0.1
-- Flask v0.12
-- gevent v1.2.1
-- greenlet v0.4.12
-- httplib2 v0.9.2
-- idna v2.5
-- itsdangerous v0.24
-- Jinja2 v2.9.5
-- kafka-python v1.3.1
-- lxml v3.6.4
-- MarkupSafe v1.0
-- multidict v2.1.4
-- packaging v16.8
-- parsel v1.1.0
-- pyasn1 v0.2.3
-- pyasn1-modules v0.0.8
-- pycparser v2.17
-- PyDispatcher v2.0.5
-- pyOpenSSL v16.2.0
-- pyparsing v2.2.0
-- python-dateutil v2.5.3
-- queuelib v1.4.2
-- requests v2.11.1
-- Scrapy v1.1.2
-- service-identity v16.0.0
-- simplejson v3.8.2
-- six v1.10.0
-- Twisted v16.4.0
-- w3lib v1.17.0
-- Werkzeug v0.12
-- yarl v0.9.8
-- zope.interface v4.3.3
-
-### Python 2 actions
-
-Python 2 actions are executed using Python 2.7.12. This is the default runtime for Python actions, unless you specify the `--kind` flag when creating or updating an action. To explicitly select this runtime, use `--kind python:2`. The following packages are available for use by Python 2 actions, in addition to the Python 2.7 standard library.
-
-- appdirs v1.4.3
-- asn1crypto v0.21.1
-- attrs v16.3.0
-- beautifulsoup4 v4.5.1
-- cffi v1.9.1
-- click v6.7
-- cryptography v1.8.1
-- cssselect v1.0.1
-- enum34 v1.1.6
-- Flask v0.11.1
-- gevent v1.1.2
-- greenlet v0.4.12
-- httplib2 v0.9.2
-- idna v2.5
-- ipaddress v1.0.18
-- itsdangerous v0.24
-- Jinja2 v2.9.5
-- kafka-python v1.3.1
-- lxml v3.6.4
-- MarkupSafe v1.0
-- packaging v16.8
-- parsel v1.1.0
-- pyasn1 v0.2.3
-- pyasn1-modules v0.0.8
-- pycparser v2.17
-- PyDispatcher v2.0.5
-- pyOpenSSL v16.2.0
-- pyparsing v2.2.0
-- python-dateutil v2.5.3
-- queuelib v1.4.2
-- requests v2.11.1
-- Scrapy v1.1.2
-- service-identity v16.0.0
-- simplejson v3.8.2
-- six v1.10.0
-- Twisted v16.4.0
-- virtualenv v15.1.0
-- w3lib v1.17.0
-- Werkzeug v0.12
-- zope.interface v4.3.3
-
-## Swift actions
-
-### Swift 3
-Swift 3 actions are executed using Swift 3.1.1  `--kind swift:3.1.1`.
-
-Swift 3.1.1 actions can use the following packages:
-- KituraNet version 1.7.6, https://github.com/IBM-Swift/Kitura-net
-- SwiftyJSON version 15.0.1, https://github.com/IBM-Swift/SwiftyJSON
-- Watson Developer Cloud SDK version 0.16.0, https://github.com/watson-developer-cloud/swift-sdk
-
-### Swift 4
-Swift 4 actions are executed using Swift 4.1  `--kind swift:4.1`.
-The default `--kind swift:default` is Swift 4.1.
-
-Swift 4.1 action runtime doesn't embed any packages, follow the instructions for [packaged swift actions](./actions.md#packaging-an-action-as-a-swift-executable) to include dependencies using a Package.swift.
-
-
-## PHP actions
-
-PHP actions are executed using PHP 7.1.18. To use this runtime, specify the `wsk` CLI parameter `--kind php:7.1` when creating or updating an action. This is the default when creating an action with file that has a `.php` extension.
-
-The following PHP extensions are available in addition to the standard ones:
-
-- bcmath
-- curl
-- gd
-- intl
-- mbstring
-- mysqli
-- pdo_mysql
-- pdo_pgsql
-- pdo_sqlite
-- soap
-- zip
-
-### Composer packages
-
-The following Composer packages are also available:
-
-- guzzlehttp/guzzle       v6.7.3
-- ramsey/uuid             v3.6.3
-
-## Docker actions
-
-Docker actions run a user-supplied binary in a Docker container. The binary runs in a Docker image based on [python:3.6.1-alpine](https://hub.docker.com/r/library/python), so the binary must be compatible with this distribution.
-
-The Docker skeleton is a convenient way to build OpenWhisk-compatible Docker images. You can install the skeleton with the `wsk sdk install docker` CLI command.
-
-The main binary program must be located in `/action/exec` inside the container. The executable receives the input arguments via a single command-line argument string which can be deserialized as a `JSON` object. It must return a result via `stdout` as a single-line string of serialized `JSON`.
-
-You may include any compilation steps or dependencies by modifying the `Dockerfile` included in the `dockerSkeleton`.
-
-## REST API
-Information about the REST API can be found [here](rest_api.md)
-
-
 ## System limits
 
 ### Actions


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services