[Experimental] Node inline task configuration

Define task configuration directly in JavaScript/TypeScript.
Inline task configuration is an experimental feature. Details are subject to change.
Task configuration can now be defined in task implementation files themselves, instead of the UI or task definition YAML files. This simplifies the files required to define a task and allows for the full expressiveness of JavaScript/TypeScript.

Writing tasks

Tasks can be defined in files that end with .airplane.js or .airplane.ts. This allows Airplane to properly discover your task when deploying. The Node SDK provides a function airplane.task, which takes two parameters: the task configuration and the task implementation.
javascript
Copied
1
// myTask.airplane.ts
2
import airplane from "airplane";
3
4
export default airplane.task(
5
// Task configuration
6
{
7
slug: "my_task",
8
name: "My Task",
9
description: "This is my task defined entirely in JavaScript!",
10
},
11
// Task implementation
12
async () => {
13
console.log("Hello World!");
14
}
15
);
No additional files are needed. Deploying this task creates an Airplane task that prints Hello World! when you run it.

Adding parameters

Parameters are included in the task configuration as objects, where the key is the parameter slug and the value is the parameter configuration. You can shorthand parameter configuration by setting the value to the parameter type. This defines a required parameter with slug and name equal to the key.
When you add parameters, you need to change your implementation function signature to accept a params object. The params object has type hints for all of the parameters defined in the task configuration.
javascript
Copied
1
// myTask.airplane.ts
2
import airplane from "airplane";
3
4
export default airplane.task(
5
// Task configuration
6
{
7
slug: "my_task",
8
name: "My Task",
9
description: "This is my task defined entirely in JavaScript!",
10
parameters: {
11
// Required integer param with slug "my_int_param" and name "my_int_param"
12
my_int_param: "integer",
13
// Optional shorttext param with slug "my_optional_text_param" that defaults to "Hello!"
14
my_optional_text_param: {
15
type: "shorttext",
16
name: "My optional text param",
17
required: false,
18
default: "Hello!",
19
options: ["Hello!", "Good morning!"],
20
},
21
},
22
},
23
// Now accepts a params argument
24
async (params) => {
25
console.log(`${params.my_optional_text_param}, ${params.my_int_param}`);
26
}
27
);
For details on the types of parameters and supported configuration options, see the task definition reference.

Task discovery

While we used a default export for the task in the above examples, you can define multiple tasks in the same file and you can use default or named exports for each of your tasks.
Airplane imports your task modules to discover and deploy them. This allows you to set up dynamic configuration and use all of the power of the JavaScript language to define your tasks. Airplane will only discover and deploy tasks that are exported.
javascript
Copied
1
// myTasks.airplane.ts
2
import airplane from "airplane";
3
4
// Discoverable by Airplane
5
export default airplane.task(
6
{...},
7
async (params) => {...}
8
);
9
10
// Discoverable by Airplane
11
export const mySecondTask = airplane.task(
12
{...},
13
async (params) => {...}
14
);
15
16
// NOT discoverable by Airplane
17
const mySecondTask = airplane.task(
18
{...},
19
async (params) => {...}
20
);

Developing and testing

You can run inline configured tasks locally using the airplane dev <taskFile> CLI command. Since you can write multiple tasks per file, you'll need to specify which task you would like to test by appending the file with ::<exportName>.
  • If you have a default export, leaving out the identifier will run the default exported task.
  • If you only have one task defined in the file, leaving out the identifier will run the task, regardless of whether its default exported or not.
  • If multiple tasks are defined in the file and none of them are default exported, leaving out the identifier will throw an error. Providing an exportName identifier that doesn't exist in the file will also throw an error.
javascript
Copied
1
// tasks.airplane.ts (default export, multiple tasks)
2
import airplane from "airplane";
3
4
export default airplane.task(...); // airplane dev tasks.airplane.ts
5
6
export const taskA = airplane.task(...); // airplane dev tasks.airplane.ts::taskA
javascript
Copied
1
// tasks.airplane.ts (no default export, multiple tasks)
2
import airplane from "airplane";
3
4
export const taskA = airplane.task(...); // airplane dev tasks.airplane.ts::taskA
5
6
export const taskB = airplane.task(...); // airplane dev tasks.airplane.ts::taskB
javascript
Copied
1
// tasks.airplane.ts (no default export, single task)
2
import airplane from "airplane";
3
4
export const taskA = airplane.task(...); // airplane dev tasks.airplane.ts OR airplane dev tasks.airplane.ts::taskA

Examples

All options in the task definition reference are supported.

Attach a resource to a task and create a schedule

javascript
Copied
1
import airplane from "airplane";
2
3
export default airplane.task(
4
{
5
slug: "my_task",
6
parameters: {
7
text: "shorttext"
8
},
9
resources: {
10
// Attach the resource with slug "backend_db" under the alias "db"
11
db: "backend_db"
12
},
13
schedules: {
14
// Create a schedule for this task that runs at midnight each day
15
midnight_daily: {
16
cron: "0 0 * * *",
17
name: "Midnight daily",
18
description: "Runs at midnight each day",
19
paramValues: {
20
text: "text param value"
21
}
22
}
23
}
24
},
25
async (params) => {...}
26
);

Pass environment variables to a task and set label constraints for self-hosted agents

javascript
Copied
1
import airplane from "airplane";
2
3
export default airplane.task(
4
{
5
slug: "my_task",
6
envVars: {
7
// Pass an env var with a value
8
MY_ENV_VAR: "MY_ENV_VAR_VALUE",
9
// Pass an env var from a defined config var
10
MY_CONFIG_ENV_VAR: {config: "MY_CONFIG_ENV_VAR_VALUE"}
11
},
12
// Run only on agents with label "region:us-west-2"
13
constraints: {
14
region: "us-west-2"
15
}
16
},
17
async () => {...}
18
);

Require requests for task execution and set a custom timeout

javascript
Copied
1
import airplane from "airplane";
2
3
export default airplane.task(
4
{
5
slug: "my_task",
6
// Set a timeout of 200 seconds
7
timeout: 200,
8
// Require requests to execute
9
requireRequests: true,
10
allowSelfApprovals: false
11
},
12
async () => {...}
13
);