For the most part, the error messages will tell you what's wrong. The changes that affect production are fairly straightforward. The changes that affect testing are a little more situationally specific, since each service's tests are uniquely unique (until RFC0110 anyway).
Upgrade all taskcluster-lib-*
, pulse-publisher
, and taskcluster-client
to the latest, which should be 10.0.0 or higher.
Upgrade azure-entities
, if used, to 4.0.0 or higher; similarly azure-blob-storage
at 3.0.0 or higher.
Configure taskcluster.rootUrl to !env TASKCLUSTER_ROOT_URL
in the defaults in config.yml
.
Do not configure a special rootUrl for testing.
Set TASKCLUSTER_ROOT_URL
to https://taskcluster.net
in Heroku.
Remove baseUrl
, authBaseUrl
, and publicUrl
everywhere.
Configure Azure like this (updating any env vars in Heroku as necessary).
Don't forget to make parallel changes in the test
section!
defaults:
azure:
accountId: !env AZURE_ACCOUNT
cryptoKey: !env AZURE_CRYPTO_KEY
signingKey: !env AZURE_SIGNING_KEY
note it's now accountId
instead of accountName
or account
.
Add TASKCLUSTER_ROOT_URL=https://taskcluster.net
to the secrets used to test the service, alongside the clientId and accessToken.
If you are using pulse, note that pulse now requires four parameters:
pulse:
username: !env PULSE_USERNAME
password: !env PULSE_PASSWORD
hostname: !env PULSE_HOSTNAME
vhost: !env PULSE_VHOST
(and you will need to add PULSE_HOSTNAME=pulse.mozilla.org and PULSE_VHOST=/ to Heroku configs)
See taskcluster-secrets for an example.
The taskcluster-lib-api
library now provides an API builder, which main.js turns into an API. So change API
to APIBuilder
and api
to builder
.
Ensure you are providing a serviceName
(that is, without taskcluster-
) and version (v1
) to the APIBuilder constructor.
Remove schemaPrefix
. The name
is no longer allowed as of bug 1463207
Replace all input and output references with the actual filename, e.g., create-frob.yml
instead of create-frob.json
or anything else.
Do not include v1/
-- that will be added automatically.
If your app sends Pulse messages, you'll need to change this file as well.
Remove all schemaPrefix
, referencePrefix
, and exchangePrefix
.
Add serviceName
, projectName
, and version
to the new Exchanges({..})
options.
Change all schema:
to indicate a bare filename, ending in .yml
.
Again, do not include v1
, as that will be added automatically.
Move all schema files from schemas/
into schemas/v1/
.
Except don't move constants.yml
- that must remain in the schemas
directory.
Any schemas with a $ref
should use a relative URI.
The reference is always to another schema document in the same directory (we prohibit refs between services), so just use something like {$ref: "foo-definition.json#"}
.
See taskcluster-secrets for a worked example of main.js
.
Require taskcluster-lib-app
as App
.
Require taskcluster-lib-validate
as SchemaSet
.
Change the require for api.js
or v1.js
to assign to builder
.
Add a dependency on taskcluster-lib-azure
, if using Azure, and require it:
const {sasCredentials} = require('taskcluster-lib-azure');
In the monitor constructor, pass a projectName
instead of project
- this shoud be the full name of the service (taskcluster-foo
).
Pass rootUrl: cfg.taskcluster.rootUrl
too.
Change the validator
component to schemaset
and use new SchemaSet
.
Pass serviceName
(the short name).
Do not pass a prefix
.
schemaset: {
requires: ['cfg'],
setup: ({cfg}) => new SchemaSet({
serviceName: 'foo',
publish: cfg.app.publishMetaData,
aws: cfg.aws,
}),
},
You will want to replace validator
with schemaset
everywhere it appears, including where it is passed to exchanges.setup
and builder.build
.
To set up an Azure entity, call sasCredentials
with the necessary four arguments.
Note that the property names have changed (tableName
and accountId
), and that the table name must be given twice (once for the SAS credentials, once for the table access):
data.MyEntity.setup({
tableName: cfg.app.myTableName,
credentials: sasCredentials({
accountId: cfg.azure.accountId,
tableName: cfg.app.myTableName,
rootUrl: cfg.taskcluster.rootUrl,
credentials: cfg.taskcluster.credentials,
}),
});
To set up the API, modify the api
section of the loader to call builder.build
, passing a rootUrl
and removing the authBaseurl
, baseUrl
, and referencePrefix
options.
The server
component should look like this:
server: {
requires: ['cfg', 'api', 'docs'],
setup: ({cfg, api, docs}) => App({
port: cfg.server.port,
env: cfg.server.env,
forceSSL: cfg.server.forceSSL,
trustProxy: cfg.server.trustProxy,
apis: [api],
}),
},
Specifically, it is passing the api
component in the list of apis.
It is still necessary to require docs
, but it is unused.
It is not necessary to call app.use
and createServer
.
If you have a publisher, remove options exchangePrefix
and referencePrefix
and add rootUrl
.
Require the schemaset
component and change the validator
parameter to await schemaset.validator(cft.taskcluster.rootUrl),
.
publisher: {
requires: ['cfg', 'monitor', 'schemaset'],
setup: async ({cfg, monitor, schemaset}) => exchanges.setup({
rootUrl: cfg.taskcluster.rootUrl,
credentials: cfg.pulse,
validator: await schemaset.validator(cfg.taskcluster.rootUrl),
publish: cfg.app.publishMetaData,
aws: cfg.aws,
monitor: monitor.prefix('publisher'),
}),
},
For the reference
component (passed to docs), remove exchangePrefix
and add rootUrl
.
reference: {
requires: ['cfg'],
setup: ({cfg}) => exchanges.reference({
rootUrl: cfg.taskcluster.rootUrl,
credentials: cfg.pulse,
}),
},
In the docs
component, references will come from the builder module (not a component) and you'll need to pass schemaset
rather than validator.schemas
:
docs: {
requires: ['cfg', 'schemaset'],
setup: ({cfg, schemaset}) => docs.documenter({
// ...
schemaset,
references: [
{name: 'api', reference: builder.reference()},
],
}),
},
If the esrvice uses a pulse listener client, e.g., QueueEvents, note that it must now receive rootUrl as a constructor arg: new QueueEvents{{rootUrl: cfg.taskcluster.rootUrl})
.
If you can typically start this service with something like NODE_ENV=test TASKCLUSTER_ROOT_URL=https://tc.example.com node src/main.js server
, do so now and solve the errors that come up. Just about any no-longer-used parameter, or newly-required parameter, has a clear error message if it's wrong. Once that's done, set to work on the tests..
This is a great time to make the tests more RFC0110 compliant! It's quite likely that's the easiest path.
Note that taskcluster-hooks
and taskcluster-secrets
are both upgraded to RFC0110 and provide some useful boilerplate.
Have a look at the taskcluster-lib-testing
docs, too -- stickyLoader
and Secrets
can be quite useful.
Once nice thing to note is the definition and use of helper.withEntity
and helper.withServer
which can take care of setting up Azure entities and a fake webserver for API testing.
One of the trickiest bits about testing now is that there are potentially two rootUrls
at play: a fake webserver is running the API under test at http://localhost:9857
, and the fakeauth
should be configured to fake auth.authenticateHawk
on that rootUrl.
But when using "real" Azure tables, you will need to initialize the Azure entity with the rootUrl given in TASKCLUSTER_ROOT_URL
, while still running everything else with the localhost rootUrl.
Also of note, App
from taskclutser-lib-app now returns an Express Server object (not an app) and does so via a Promise.
You may also need to modify any API setup just like in main.js
.
If you use the schema
utilty from taskcluster-lib-testing
, note that it now takes a schemasetOptions
argument (pass folder
and serviceNam
) and requires a full schema id, under the test rootUrl.
That will be something like https://tc-tests.localhost/schemas/test/case1.json#
-- note carefully the .json#
suffix.