A web server for supporting the taskcluster-ui repository. This service acts as a GraphQL gateway to the Taskcluster REST APIs, and supports user authentication flows.
It supports the queries, mutations, and subscriptions of Taskcluster APIs used by the web application.
Configuration is done via taskcluster-lib-config like all
other Taskcluster services. The main configuration file is config.yml
, and
that refers to environment variables. In production, those environment
variables are provided as part of the deployment. During development,
configuration can be overridden in user-config.yml
.
To run this service locally, install dependencies using yarn
.
The taskcluster.rootUrl
configuration setting is required. Either set
TASKCLUSTER_ROOT_URL
in your environment, or copy user-config-template.yml
to user-config.yml
and edit it to include the rootUrl
for the Taskcluster
instance you are accessing; for example https://taskcluster.net
.
The Taskcluster team has a series of best practices for this service which may help guide you in modifying the source code and making a pull request. That is enough to run the service, so if that's all you need, skip down to "Starting".
This service requires Taskcluster credentials to support user login and receiving pulse messages, but this is not required for development of most features.
To set up Taskcluster credentials, use
the taskcluster
tool to set
TASKCLUSTER_ROOT_URL
, TASKCLUSTER_CLIENT_ID
, and TASKCLUSTER_ACCESS_TOKEN
in your shell:
$ eval $(./taskcluster signin --name taskcluster-web-server)
Pulse messages are entirely optional, and most server components do not require them. If you do not configure pulse, the server will act as if no pulse messages are received, which is sufficient for most development work.
To receive pulse messages, you will also need a Pulse user. For Mozilla's
Pulse, you can get such credentials at https://pulseguardian.mozilla.org. Use
hostname pulse.mozilla.org
and vhost /
. In this situation, set the
namespace to match the username.
In any case, use the command yarn start
to start the service.
You should see the following message in the console, for example, using port 3050:
Web server running on port 3050.
Open the interactive GraphQL Playground, schema explorer and docs in your browser at:
http://localhost:3050
The taskcluster-ui
service expects this service to run on port 3050.
To pass credentials to the server from the GraphQL Playground, click the "HTTP Headers" section, and paste a JSON object with a key of "Authorization" with a value of "Bearer YOUR_TC_TOKEN", such as:
{
"Authorization": "Bearer eyJ0...yXlBw"
}
You can find your TC token in localStorage after signing into the UI.
Taskcluster supports a number of "login strategies" to support users logging into the UI.
See docs/login-strategies.md
for more information.
Note that in most cases setup of login strategies is not required for development of this service.
Query a task, selecting status state and name:
query Sample {
task(taskId: "XeC1Y4NjQp25SbK0o8ab7w") {
status {
state
}
metadata {
name
}
}
}
Select the taskId for all tasks in a task group, and select whether there is another page:
query Sample {
taskGroup(taskGroupId: "AMfy-mopRaOCQlNW5IhOeQ") {
pageInfo {
hasNextPage
}
edges {
node {
taskId
}
}
}
}
Create a tutorial task:
mutation Sample($taskId: ID!, $task: TaskInput!) {
createTask(taskId: $taskId, task: $task) {
state
}
}
Variables:
{
"taskId": "fN1SbArXTPSVFNUvaOlinQ",
"task": {
"provisionerId": "aws-provisioner-v1",
"workerType": "tutorial",
"retries": 0,
"created": "2018-03-07T05:53:06.683Z",
"deadline": "2018-03-07T06:03:06.683Z",
"expires": "2019-03-07T06:03:06.683Z",
"payload": {
"image": "ubuntu:13.10",
"command": [
"/bin/bash",
"-c",
"for ((i=1;i<=600;i++)); do echo $i; sleep 1; done"
],
"maxRunTime": 600
},
"metadata": {
"name": "GraphQL Tutorial Task",
"description": "Task created via GraphQL",
"owner": "eli@eliperelman.com",
"source": "https://localhost:3050/"
}
}
}
Subscribe to the tasks entering the PENDING
state within a task group,
selecting its state:
subscription Sample {
tasksPending(taskGroupId: "fN1SbArXTPSVFNUvaOlinQ") {
status {
state
}
}
}
Subscribe to multiple task group subscriptions, selecting the state from each status change:
subscription Sample($taskGroupId: ID!, $subscriptions: [TaskSubscriptions]!) {
tasksSubscriptions(taskGroupId: $taskGroupId, subscriptions: $subscriptions) {
...on TaskFailed {
status {
state
}
}
...on TaskException {
status {
state
}
}
...on TaskCompleted {
status {
state
}
}
}
}
Variables:
{
"taskGroupId": "fN1SbArXTPSVFNUvaOlinQ",
"subscriptions": [
"tasksException",
"tasksFailed",
"tasksCompleted"
]
}