Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
test(testCase.path, function() {
// Load test data
var filePath = testCase.path;
// Prefix with basePath if a basePath is given
if (options.basePath) {
filePath = path.join(options.basePath, filePath);
}
var data = fs.readFileSync(filePath, {encoding: 'utf-8'});
var json = JSON.parse(data);
// Find schema
var schema = libUrls.schema(libUrls.testRootUrl(), options.serviceName, testCase.schema);
// Validate json
var error = validate(json, schema);
// Test errors
if (testCase.success) {
if (error !== null) {
debug('Errors: %j', error);
}
assert(error === null,
'Schema doesn\'t match test for ' + testCase.path);
} else {
assert(error !== null,
'Schema matches unexpectedly test for ' + testCase.path);
}
});
exports.start = function(clients, {rootUrl}={}) {
assert(rootUrl, 'rootUrl option is required');
const authPath = url.parse(libUrls.api(rootUrl, 'auth', 'v1', '/authenticate-hawk')).pathname;
nock(rootUrl, {encodedQueryParams: true, allowUnmocked: true})
.persist()
.filteringRequestBody(/.*/, '*')
.post(authPath, '*')
.reply(200, function(uri, body) {
let scopes = [];
let from = 'client config';
let ext = null;
let clientId = null;
if (body.authorization) {
let authorization = hawk.utils.parseAuthorizationHeader(body.authorization);
clientId = authorization.id;
scopes = clients[clientId];
ext = authorization.ext;
} else {
// The following is a hacky reproduction of the bewit logic in
serviceName = reference.exchangePrefix.split('/')[1].replace('taskcluster-', '');
}
}
reference.serviceName = serviceName;
if (!reference.version) {
reference.version = 'v1';
}
delete reference.name;
delete reference.baseUrl;
// Someday, when we are not munging the reference above, this can allow
// multiple versions of the schema. For now, assign the only schema.
if (reference.exchangePrefix) {
reference.$schema = libUrls.schema(rootUrl, 'common', 'exchanges-reference-v0.json#');
} else {
reference.$schema = libUrls.schema(rootUrl, 'common', 'api-reference-v0.json#');
}
});
};
continue;
}
if (ajv.errors) {
ajv
.errorsText(ajv.errors, {separator: '%%/%%', dataVar: 'reference'})
.split('%%/%%')
.forEach(err => problems.push(`${filename}: ${err}`));
}
}
}
// If we're still doing OK, let's check that the schema references from various
// reference entries are correctly formatted
if (!problems.length) {
const metaschemaUrl = libUrls.schema(references.rootUrl, 'common', 'metaschema.json#');
// check that a schema link is relative to the service
for (let {filename, content} of references.references) {
const checkRelativeSchema = (name, serviceName, schemaName, i) => {
if (schemaName.match(/^\/|^[a-z]*:|^\.\./)) {
problems.push(`${filename}: entries[${i}].${name} is not relative to the service`);
return;
}
const fullSchema = libUrls.schema(references.rootUrl, serviceName, schemaName);
const schema = references.getSchema(fullSchema, {skipValidation: true});
if (!schema) {
problems.push(`${filename}: entries[${i}].${name} does not exist`);
} else if (schema.$schema !== metaschemaUrl) {
problems.push(`${serviceName}/${schemaName}'s $schema is not the metaschema`);
}
};
module.exports = ({ queue }, isAuthed, rootUrl) => {
const urls = withRootUrl(rootUrl);
const withUrl = ({ method, taskId, artifact, runId }) => {
const hasRunId = !isNil(runId);
const isPublic = /^public\//.test(artifact.name);
// We don't want to build signed URLs for public artifacts,
// even when credentials are present -- users often
// copy/paste artifact URLs, and this would likely lead to
// people copy/pasting time-limited, signed URLs which would
// (a) have a long ?bewit=.. argument and
// (b) probably not work after that bewit expires.
// We could use queue.buildUrl, but this creates URLs where the artifact
// name has slashes encoded. For artifacts we specifically allow slashes
// in the name unencoded, as this make things like `wget ${URL}` create
// files with nice names.
if (isPublic) {
return {
async onMessage(message) {
let {status} = message.payload;
// If task was canceled, we don't send a notification since this was a deliberate user action
if (status.state === 'exception') {
if (this.ignoreTaskReasonResolved.includes((_.last(status.runs) || {}).reasonResolved)) {
return null;
}
}
// Load task definition
let taskId = status.taskId;
let task = await this.queue.task(taskId);
let href = libUrls.ui(this.rootUrl, `tasks/${taskId}`);
let groupHref = libUrls.ui(this.rootUrl, `groups/${taskId}/tasks`);
let runCount = status.runs.length;
return Promise.all(message.routes.map(entry => {
let route = entry.split('.');
// convert from on- syntax to state. e.g. on-exception -> exception
let decider = _.join(_.slice(route[route.length - 1], 3), '');
if (decider !== 'any' && status.state !== decider) {
return null;
}
let ircMessage = `Task "${task.metadata.name}" complete with status '${status.state}'. Inspect: ${href}`;
switch (route[1]) {
case 'irc-user': {
if (_.has(task, 'extra.notify.ircUserMessage')) {
async onMessage(message) {
let {status} = message.payload;
// If task was canceled, we don't send a notification since this was a deliberate user action
if (status.state === 'exception') {
if (this.ignoreTaskReasonResolved.includes((_.last(status.runs) || {}).reasonResolved)) {
return null;
}
}
// Load task definition
let taskId = status.taskId;
let task = await this.queue.task(taskId);
let href = libUrls.ui(this.rootUrl, `tasks/${taskId}`);
let groupHref = libUrls.ui(this.rootUrl, `groups/${taskId}/tasks`);
let runCount = status.runs.length;
return Promise.all(message.routes.map(entry => {
let route = entry.split('.');
// convert from on- syntax to state. e.g. on-exception -> exception
let decider = _.join(_.slice(route[route.length - 1], 3), '');
if (decider !== 'any' && status.state !== decider) {
return null;
}
let ircMessage = `Task "${task.metadata.name}" complete with status '${status.state}'. Inspect: ${href}`;
switch (route[1]) {
case 'irc-user': {
}
reference.serviceName = serviceName;
if (!reference.version) {
reference.version = 'v1';
}
delete reference.name;
delete reference.baseUrl;
// Someday, when we are not munging the reference above, this can allow
// multiple versions of the schema. For now, assign the only schema.
if (reference.exchangePrefix) {
reference.$schema = libUrls.schema(rootUrl, 'common', 'exchanges-reference-v0.json#');
} else {
reference.$schema = libUrls.schema(rootUrl, 'common', 'api-reference-v0.json#');
}
});
};
return _.mapValues(this._schemas, (schema, jsonName) => {
const newSchema = _.clone(schema);
newSchema.$id = libUrls.schema(rootUrl, this.cfg.serviceName, jsonName + '#');
// rewrite a relative `/schemas//
}
if (!repoconf) { return; }
let groupState = 'pending';
let taskGroupId = 'nonexistent';
let graphConfig;
// Now we can try processing the config and kicking off a task.
try {
graphConfig = this.intree({
config: repoconf,
payload: message.payload,
validator: context.validator,
schema: {
0: libUrls.schema(this.rootUrl, 'github', 'v1/taskcluster-github-config.yml'),
1: libUrls.schema(this.rootUrl, 'github', 'v1/taskcluster-github-config.v1.yml'),
},
});
if (graphConfig.tasks !== undefined && !Array.isArray(graphConfig.tasks)) {
throw new Error('tasks field of .taskcluster.yml must be array of tasks or empty array');
}
if (!graphConfig.tasks || graphConfig.tasks.length === 0) {
debug(`intree config for ${organization}/${repository}@${sha} compiled with zero tasks. Skipping.`);
return;
}
} catch (e) {
debug(`.taskcluster.yml for ${organization}/${repository}@${sha} was not formatted correctly.
Leaving comment on Github.`);
await this.createExceptionComment({instGithub, organization, repository, sha, error: e, pullNumber});
return;
}