feat: Support version when create / update action (#65)
* feat: Support version when create / update action
The [REST API](https://console.bluemix.net/apidocs/98-ibm-bluemix-openwhisk?=undefined&language=node&env_id=ibm:yp:eu-gb#create-or-update-an-action) support version number, when create or update action. The parameter is optional and if it is empty the system increment the patch version number.
When action invoke the system store the version number in the log. Very useful to know what version of the action have invoked when investigating a bug.
* doc: Add version documentation of create / update action
diff --git a/README.md b/README.md
index c8e41fd..ab80a96 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
## installation
-```
+```bash
$ npm install openwhisk
```
@@ -19,7 +19,7 @@
This client library can use environment parameters to automatically configure the authentication credentials, platform endpoint and namespace. These parameters are defined within the Node.js runtime environment in OpenWhisk. Unless you want to override these values, you can construct the client instance without further configuration.
-```
+```javascript
var openwhisk = require('openwhisk');
function action() {
@@ -32,7 +32,7 @@
_All methods return a Promise resolved asynchronously with the results. Failures are available through the catch method._
-```
+```javascript
ow.resource.operation().then(function () { // success! }).catch(function (err) { // failed! })
```
@@ -40,7 +40,7 @@
_**Please note**: Due to [an issue](https://github.com/openwhisk/openwhisk/issues/1751) with the Node.js runtime in OpenWhisk, environment variables used by the constructor are not available until the invocation function handler is called. If you want to define the client instance outside this function, you will need to manually pass in the constructor options ._
-```
+```javascript
var openwhisk = require('openwhisk');
// DOES NOT WORK! Environment parameters not set.
var ow = openwhisk();
@@ -54,7 +54,7 @@
### outside openwhisk platform
-```
+```javascript
var openwhisk = require('openwhisk');
var options = {apihost: 'openwhisk.ng.bluemix.net', api_key: '...'};
var ow = openwhisk(options);
@@ -92,7 +92,7 @@
### invoke action, blocking for result
-```
+```javascript
const name = 'reverseWords'
const blocking = true, result = true
const params = {msg: 'these are some words to reverse'}
@@ -106,7 +106,7 @@
### fire trigger
-```
+```javascript
const name = 'eventTrigger'
const params = {msg: 'event trigger message string'}
ow.triggers.invoke({name, params}).then(result => {
@@ -118,7 +118,7 @@
### create action from source file
-```
+```javascript
const name = 'reverseWords'
const action = fs.readFileSync('source.js', {encoding: 'utf8'})
@@ -131,7 +131,7 @@
### create action from zip package
-```
+```javascript
const name = 'reverseWords'
const action = fs.readFileSync('package.zip')
@@ -144,7 +144,7 @@
### retrieve action resource
-```
+```javascript
const name = 'reverseWords'
ow.actions.get(name).then(action => {
console.log('action resource', action)
@@ -155,7 +155,7 @@
### chaining calls
-```
+```javascript
ow.actions.list()
.then(actions => ow.actions.invoke(actions))
.then(result => ...)
@@ -163,7 +163,7 @@
### list packages
-```
+```javascript
ow.packages.list().then(packages => {
packages.forEach(package => console.log(package.name))
}).catch(err => {
@@ -173,7 +173,7 @@
### update package parameters
-```
+```javascript
const name = 'myPackage'
const package = {
parameters: [
@@ -191,7 +191,7 @@
### create trigger feed from alarm package
-```
+```javascript
// alarmTrigger MUST already exist in default namespace
const params = {cron: '*/8 * * * * *', trigger_payload: {name: 'James'}}
const name = '/whisk.system/alarms/alarm'
@@ -220,7 +220,7 @@
### list resources
-```
+```javascript
ow.actions.list()
ow.activations.list()
ow.triggers.list()
@@ -231,7 +231,7 @@
Query parameters for the API calls are supported (e.g. limit, skip, etc.) by passing an object with the named parameters as the first argument.
-```
+```javascript
ow.actions.list({skip: 100, limit: 50})
```
@@ -240,7 +240,7 @@
### retrieve resource
-```
+```javascript
ow.actions.get({name: '...'})
ow.activations.get({name: '...'})
ow.triggers.get({name: '...'})
@@ -254,20 +254,20 @@
This method also supports passing the `name` property directly without wrapping within an object.
-```
+```javascript
const name = "actionName"
ow.actions.get(name)
```
If you pass in an array for the first parameter, the `get` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
-```
+```javascript
ow.actions.get(["a", {name: "b"}])
```
### delete resource
-```
+```javascript
ow.actions.delete({name: '...'})
ow.triggers.delete({name: '...'})
ow.rules.delete({name: '...'})
@@ -279,20 +279,20 @@
This method also supports passing the `name` property directly without wrapping within an object.
-```
+```javascript
const name = "actionName"
ow.actions.delete(name)
```
If you pass in an array for the first parameter, the `delete` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
-```
+```javascript
ow.actions.delete(["a", {name: "b"}])
```
### invoke action
-```
+```javascript
ow.actions.invoke({name: '...'})
```
@@ -308,20 +308,20 @@
This method also supports passing the `name` property directly without wrapping within an object.
-```
+```javascript
const name = "actionName"
ow.actions.invoke(name)
```
If you pass in an array for the first parameter, the `invoke` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
-```
+```javascript
ow.actions.invoke(["a", {name: "b", blocking: true}])
```
### create & update action
-```
+```javascript
ow.actions.create({name: '...', action: 'function main() {};'})
ow.actions.update({name: '...', action: 'function main() {};'})
```
@@ -334,16 +334,17 @@
- `namespace` - set custom namespace for endpoint
- `params` - object containing default parameters for the action (default: `{}`)
- `kind` - runtime environment parameter, ignored when `action` is an object (default: `nodejs:default`)
+- `version` - set semantic version of the action. If parameter is empty when create new action openwisk generate 0.0.1 value when update an action increase the patch version.
If you pass in an array for the first parameter, the `create` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
-```
+```javascript
ow.actions.create([{...}, {...}])
```
### fire trigger
-```
+```javascript
ow.triggers.invoke({name: '...'})
```
@@ -353,20 +354,20 @@
This method also supports passing the `name` property directly without wrapping within an object.
-```
+```javascript
const name = "actionName"
ow.triggers.invoke(name)
```
If you pass in an array for the first parameter, the `invoke` call will be executed for each array item. The function returns a Promise which resolves with the results when all operations have finished.
-```
+```javascript
ow.triggers.invoke(["a", {name: "b", blocking: true}])
```
### create & update trigger
-```
+```javascript
ow.triggers.create({name: '...'})
ow.triggers.update({name: '...'})
```
@@ -377,7 +378,7 @@
### create & update packages
-```
+```javascript
ow.packages.create({name: '...'})
ow.packages.update({name: '...'})
```
@@ -388,7 +389,7 @@
### create & update rule
-```
+```javascript
ow.rules.create({name: '...', action: '...', trigger: '...'})
ow.rules.update({name: '...', action: '...', trigger: '...'})
```
@@ -402,7 +403,7 @@
### enable & disable rule
-```
+```javascript
ow.rules.enable({name: '...'})
ow.rules.disable({name: '...'})
```
@@ -412,7 +413,7 @@
### create & delete feeds
-```
+```javascript
ow.feeds.create({feedName: '...', trigger: '...'})
ow.feeds.delete({feedName: '...', trigger: '...'})
```
@@ -431,7 +432,7 @@
### list routes
-```
+```javascript
ow.routes.list()
```
@@ -446,7 +447,7 @@
### delete routes
-```
+```javascript
ow.routes.delete({basepath: '...'})
```
@@ -455,7 +456,7 @@
- `operation` - HTTP methods
### add route
-```
+```javascript
ow.routes.create({relpath: '...', operation: '...', action: '...'})
```
@@ -468,13 +469,13 @@
Setting an environment parameter (`NODE_DEBUG=request`) will dump the HTTP requests from the client library and responses received to `stderr`.
-```
+```bash
NODE_DEBUG=request node script.js
```
This parameter can also be set dynamically at runtime, provided this happens before the `openwhisk` module is required.
-```
+```javascript
process.env.NODE_DEBUG='request';
var openwhisk = require('openwhisk');
```
@@ -483,16 +484,16 @@
### unit tests
-```
-npm test
+```bash
+$ npm test
```
### integration tests
*Please [see the instructions](https://github.com/openwhisk/openwhisk-client-js/tree/master/test/integration) for setting up the integration test environment prior to running these tests.*
-```
-npm run-script test-integration
+```bash
+$ npm run-script test-integration
```
**Note:** The test integration runs in secure mode by default, which means that all trusted signers must be present and available to the client process.
@@ -504,8 +505,8 @@
Alternatively, you can run the `prepIntegrationTests.sh` script using guest credentials or by specifying specific credentials.
Run the script with openwhisk credentials:
-```
-./test/integration/prepIntegrationTests.sh <your key in the form of ABCD:EFGH> <openwhisk instance hostname> <openwhisk namespace> <api gatewaytoken>
+```bash
+$ ./test/integration/prepIntegrationTests.sh <your key in the form of ABCD:EFGH> <openwhisk instance hostname> <openwhisk namespace> <api gatewaytoken>
```
The `prepIntegrationTests.sh` script is designed to give you feedback if it detects a setting that is not correct on your machine. ex: `node 6 or above is not detected`
@@ -517,9 +518,9 @@
**Note:** Ensure that you use guest credentials with the wsk CLI.
To compile down to ECMA5 run the following command:
-1 `npm run code-coverage-build`
+1 `$ npm run code-coverage-build`
To generate combined reports of both the unit and integration tests, run the following command:
-2 `npm run code-coverage-run <key> <host> <namespace> <token> <options>`
+2 `$ npm run code-coverage-run <key> <host> <namespace> <token> <options>`
The report is viewable under `/coverage`. Click **`/coverage/index.html`** to view the full report.
diff --git a/lib/actions.js b/lib/actions.js
index 0bda53a..05dde00 100644
--- a/lib/actions.js
+++ b/lib/actions.js
@@ -53,6 +53,10 @@
body.parameters = Object.keys(options.params).map(key => ({ key, value: options.params[key] }))
}
+ if(options.version){
+ body.version = options.version;
+ }
+
return body
}
}
diff --git a/test/unit/actions.test.js b/test/unit/actions.test.js
index fbb98b7..cc75ec8 100644
--- a/test/unit/actions.test.js
+++ b/test/unit/actions.test.js
@@ -332,3 +332,23 @@
const actions = new Actions()
t.throws(() => actions.create({name: '12345'}), /Missing mandatory action/)
})
+
+test('create a new action with version parameter', t => {
+ t.plan(4)
+ const ns = '_'
+ const client = {}
+ const action = 'function main() { // main function body};'
+ const version = '1.0.0'
+
+ const actions = new Actions(client)
+
+ client.request = (method, path, options) => {
+ t.is(method, 'PUT')
+ t.is(path, `namespaces/${ns}/actions/12345`)
+ t.deepEqual(options.qs, {})
+ t.deepEqual(options.body, {exec: {kind: 'nodejs:default', code: action}, version: '1.0.0'})
+ }
+
+ return actions.create({name: '12345', action, version})
+
+})