From 17d6ab83671eb5d0014a7bd299d0f6c53db50801 Mon Sep 17 00:00:00 2001 From: MTRNord Date: Fri, 15 Dec 2017 14:12:25 +0100 Subject: [PATCH 1/4] Add CircleCI Integration Signed-off-by: MTRNord --- config/integrations/circleci.yaml | 8 ++ .../circleci/circleci-config.component.html | 63 ++++++++++ .../circleci/circleci-config.component.scss | 19 +++ .../circleci/circleci-config.component.ts | 116 ++++++++++++++++++ web/app/shared/integration.service.ts | 4 + web/app/shared/models/integration.ts | 6 + web/public/img/avatars/circleci.png | Bin 0 -> 4381 bytes 7 files changed, 216 insertions(+) create mode 100644 config/integrations/circleci.yaml create mode 100644 web/app/configs/circleci/circleci-config.component.html create mode 100644 web/app/configs/circleci/circleci-config.component.scss create mode 100644 web/app/configs/circleci/circleci-config.component.ts create mode 100644 web/public/img/avatars/circleci.png diff --git a/config/integrations/circleci.yaml b/config/integrations/circleci.yaml new file mode 100644 index 0000000..31de701 --- /dev/null +++ b/config/integrations/circleci.yaml @@ -0,0 +1,8 @@ +type: "complex-bot" +integrationType: "circleci" +enabled: true +name: "CircleCI" +about: "Sends CircleCI build results into the room" +avatar: "img/avatars/circleci.png" +upstream: + type: "vector" diff --git a/web/app/configs/circleci/circleci-config.component.html b/web/app/configs/circleci/circleci-config.component.html new file mode 100644 index 0000000..4685cec --- /dev/null +++ b/web/app/configs/circleci/circleci-config.component.html @@ -0,0 +1,63 @@ +
+ +
+ +

Configure CircleCI hooks

+
+
+
+
+
+
.circleci/config.yml configuration
+ The following will need to be added to your .circleci/config.yml file: +
{{ circleYaml }}
+
+
+
Your CircleCI hooks
+
+ + + + +
+
+
+ {{ repo.repoKey }} + + +
+ + + +
+
+
+
Hooks from other users in the room
+
+
+ {{ repo.repoKey }} (added by {{ repo.ownerId }}) + +
{{ repo.template }}
+
+
+
+
+
\ No newline at end of file diff --git a/web/app/configs/circleci/circleci-config.component.scss b/web/app/configs/circleci/circleci-config.component.scss new file mode 100644 index 0000000..0430df4 --- /dev/null +++ b/web/app/configs/circleci/circleci-config.component.scss @@ -0,0 +1,19 @@ +// component styles are encapsulated and only applied to their components +.list { + margin-top: 5px; +} + +.removable { + margin-top: 3px; +} + +.other-items-title { + margin-top: 25px; + margin-bottom: 0; +} + +.yaml { + border: 1px solid #ccc; + background: #eee; + padding: 5px; +} \ No newline at end of file diff --git a/web/app/configs/circleci/circleci-config.component.ts b/web/app/configs/circleci/circleci-config.component.ts new file mode 100644 index 0000000..c524063 --- /dev/null +++ b/web/app/configs/circleci/circleci-config.component.ts @@ -0,0 +1,116 @@ +import { Component } from "@angular/core"; +import { CircleCiIntegration } from "../../shared/models/integration"; +import { ModalComponent, DialogRef } from "ngx-modialog"; +import { ConfigModalContext } from "../../integration/integration.component"; +import { ToasterService } from "angular2-toaster"; +import { ApiService } from "../../shared/api.service"; + +@Component({ + selector: "my-circleci-config", + templateUrl: "./circleci-config.component.html", + styleUrls: ["./circleci-config.component.scss", "./../config.component.scss"], +}) +export class CircleCiConfigComponent implements ModalComponent { + + public integration: CircleCiIntegration; + + public isUpdating = false; + public repoKey = ""; + public repoTemplate = ""; + public circleYaml = ""; + + private roomId: string; + private scalarToken: string; + private knownRepos: string[] = []; + private visibleTemplates = []; + + constructor(public dialog: DialogRef, + private toaster: ToasterService, + private api: ApiService) { + this.integration = dialog.context.integration; + this.roomId = dialog.context.roomId; + this.scalarToken = dialog.context.scalarToken; + + this.circleYaml = "notify:\n webhooks:\n - url: " + this.integration.webhookUrl; + + this.calculateKnownRepos(); + this.reset(); + } + + private calculateKnownRepos() { + for (let repo of this.integration.repoTemplates) + this.knownRepos.push(repo.repoKey); + for (let immutableRepo of this.integration.immutableRepoTemplates) + this.knownRepos.push(immutableRepo.repoKey); + } + + public toggleTemplate(repoKey: string) { + let idx = this.visibleTemplates.indexOf(repoKey); + if (idx === -1) this.visibleTemplates.push(repoKey); + else this.visibleTemplates.splice(idx, 1); + } + + public isTemplateToggled(repoKey: string) { + return this.visibleTemplates.indexOf(repoKey) !== -1; + } + + public editTemplate(repoKey: string) { + this.toggleTemplate(repoKey); + let repoConfig = this.integration.repoTemplates.find(r => r.repoKey === repoKey); + repoConfig.newTemplate = repoConfig.template; + } + + public saveTemplate(repoKey: string) { + let repoConfig = this.integration.repoTemplates.find(r => r.repoKey === repoKey); + repoConfig.template = repoConfig.newTemplate; + this.updateTemplates().then(() => this.toggleTemplate(repoKey)); + } + + public addRepository() { + if (!this.repoKey || this.repoKey.trim().length === 0) { + this.toaster.pop("warning", "Please enter a repository"); + return; + } + if (this.knownRepos.indexOf(this.repoKey) !== -1) { + this.toaster.pop("error", "Repository " + this.repoKey + " is already being tracked"); + return; + } + + this.integration.repoTemplates.push({repoKey: this.repoKey, template: this.repoTemplate, newTemplate: ""}); + this.updateTemplates().then(() => this.reset()); + } + + private reset() { + this.repoKey = ""; + this.repoTemplate = "%{build_num}#%{build_num} (%{branch} - %{commit} : %{committer_name}): %{outcome}\n Build details : %{build_url}\n"; + } + + public removeRepository(repoKey: string) { + for (let i = 0; i < this.integration.repoTemplates.length; i++) { + if (this.integration.repoTemplates[i].repoKey === repoKey) { + this.integration.repoTemplates.splice(i, 1); + this.updateTemplates().then(() => this.reset()); + return; + } + } + + this.toaster.pop("error", "Could not find target repository"); + } + + public updateTemplates() { + this.isUpdating = true; + return this.api.updateIntegrationState(this.roomId, this.integration.type, this.integration.integrationType, this.scalarToken, { + repoTemplates: this.integration.repoTemplates + }).then(response => { + this.integration.repoTemplates = response.repoTemplates; + this.integration.immutableRepoTemplates = response.immutableRepoTemplates; + this.calculateKnownRepos(); + this.isUpdating = false; + this.toaster.pop("success", "Repositories updated"); + }).catch(err => { + this.toaster.pop("error", err.json().error); + console.error(err); + this.isUpdating = false; + }); + } +} diff --git a/web/app/shared/integration.service.ts b/web/app/shared/integration.service.ts index c4fe7d2..67c5e5e 100644 --- a/web/app/shared/integration.service.ts +++ b/web/app/shared/integration.service.ts @@ -4,6 +4,7 @@ import { RssConfigComponent } from "../configs/rss/rss-config.component"; import { ContainerContent } from "ngx-modialog"; import { IrcConfigComponent } from "../configs/irc/irc-config.component"; import { TravisCiConfigComponent } from "../configs/travisci/travisci-config.component"; +import { CircleCiConfigComponent } from "../configs/circleci/circleci-config.component"; import { CustomWidgetConfigComponent } from "../configs/widget/custom_widget/custom_widget-config.component"; import { YoutubeWidgetConfigComponent } from "../configs/widget/youtube/youtube-config.component"; import { TwitchWidgetConfigComponent } from "../configs/widget/twitch/twitch-config.component"; @@ -28,6 +29,9 @@ export class IntegrationService { "travisci": { component: TravisCiConfigComponent, }, + "circleci": { + component: CircleCiConfigComponent, + }, }, "bridge": { "irc": { diff --git a/web/app/shared/models/integration.ts b/web/app/shared/models/integration.ts index 8f02e8c..c28eaeb 100644 --- a/web/app/shared/models/integration.ts +++ b/web/app/shared/models/integration.ts @@ -26,6 +26,12 @@ export interface TravisCiIntegration extends Integration { webhookUrl: string; // immutable } +export interface CircleCiIntegration extends Integration { + repoTemplates: { repoKey: string, template: string, newTemplate: string }[]; // newTemplate is local + immutableRepoTemplates: { repoKey: string, template: string, ownerId: string }[]; + webhookUrl: string; // immutable +} + export interface IRCIntegration extends Integration { availableNetworks: { name: string, id: string }[]; channels: { [networkId: string]: string[] }; diff --git a/web/public/img/avatars/circleci.png b/web/public/img/avatars/circleci.png new file mode 100644 index 0000000000000000000000000000000000000000..1e9ba51a4c024cc125969d4adc3d7f4122c2e04f GIT binary patch literal 4381 zcmV+&5#sKNP);k(;sc>r z^K{hQE~;nv;on1kZ&a>G^|U|cmjG`AeAbdNp*rUVfy;n^r@s9q84z<>e|Os(UOVF+tc8(*xnv&!7TO-%u-Z_IZQuIBK1*A|5+ooQpP zpu4TFVm@5A7>kdx9CJS~&vn~}CNGO4=cm`U_g2EVs{yW$TrxgKb`5Z%n|2QaK6F%~ z*`D^N-8O98G8Br$r{%~#%W!Z@;Rqx8NI2Ru*KNbDydQ&&EwhZs6Tne!*gH(IfUlX! z)8BSp*|^ayqh$v;7;Bzw;9+2t3wjQBjEKa7Q>Jgr^=^FL4TEI`I2eh4(Wn^?uDb}x zTr=gwH=N!Vf9ry=(g@9qpCl&mIOyndMGP|lLPn7J>F)M*<(Vmg5wZBVtYepynrDm3a$Fo78Kx+vmC~{< ztdW&ZUEK)$bt%e*agCJX%*-U0zf|Z21>KESzkMge!L0`B1aluvO;({73>jc6+Pna` zuq;`_xXJNW-^(a|L%EGPFnM2;y_l=lc*QCc0k^gr5L&2emK%M5nHfB_E0nx~5+8wUH_FBBfb=vA3DovzK77Q%>Fd|WPPZcrgk z_5DranPkU`!9E{QtQAQ-2%K9nRYjuko~Znj-P3-*pE`n(_!kX^|m3kUn~z{zw%bq zJ}9bRPxrL{(nk#?(Z8V;{@o&->{ttOtB(@C5RS#C?tQ=j z)HS?yDlpa;N$_D%f)~@;>iFc}RqUPPuLWN4%fG7Gr%!AEa_ZmWY!$BRPu}^qU;bTZ zeQQ>gOUci0d5$Xk)IBi(BHHMO7(}1T%$P9fIBKnu>FL;@aHk)>1!i;l;<}H257Kz) zSjbHALyS?my5f)KxtE9QgXyC)j!pm#1SIfoTJ-HoF1iNDh-tOdSqzMpi`m7m!VjViSvN#TsN%RWJQ~oxngTWTZVjj3vY1(H6Gx`OUEK~P^shumDW&W zVumZG9QAy5%#j+ugF|GOQQ5AYApDCPhD^Zm{tnLXWl@^}9vMp+?ML9O;JoH9 zmun||;%8q0QZ7g;7*QDqH5y<$$9z1>Qx;>I$~KZ8t@AYNLq(5-8V#@*?@uQyS*pYVa1vpR1rTt3a&D7e? zvbV!g)az2qS-O6Zs>uMW;Mw$>3afDCl^`XTBP<2Y&tPdy1~`+=t-+(AKXoWS8NaD1 z0N$<|5tVIFgN-Zz)~$FS__s>CQRUHWPsfwx+Obk&Cj)gup6DWqz74e+V89M$Z=$jj z=?=zR?S>(B9PjsN6xjkb9AH-6^^u4yqGAc=a($+|&6SO-M3^)5S?*$RYCOO|y1RWH zT8WGfeqkruzwe5zeAz+I1B_@d)Odga?4FLB5xpMw20wmg@5)}}mOU#qW-j@e9Z!*5 z{t>-rHGeSLa+*RvIxuU?v7hWva%J2~?udu`ihH_bMjd&y_gne25UEI|nsap^;1 zoNLl+mb*GbYoUh}Og zvJhdu=2tfiRE}^H!fI9Lfnw?}7egi&__m08ULjBAlO#W(@zSxDWIps-1b~4vQpt|> z6?M|oWYyaZM`v;}0X4xuK)0sDqu+Kbv3*eHUVM}l2)u^(i_b9X%=x&^i2zuU=3bD= zUJF6=IeW&$S%=Ev@4X2}54-#Sh;KPkkI**d5@2YSIre03vehh*-S*jEQPt#*&Z-KgFjq#G>qzWN!dc?*@O3 ze4J-B2l?_|6_XsoIZK{ zqrmH)Dmp-m-XD%7&h}A5Nz_FXlSIrqw6ddsLtv-H{OA4$KN*W|ZFNvOJ(YAImO8RB z7;QPtXB`Do*BC$6fk*wXI4f)EZu?;Wqx(!Y1RPf2Q+=mT(9uS9T{zMl^;gHxgyyyU zts~|spKE*qATsdHxldC*`|6AT7npkDG{E(OBt;Se`MbcB>8V`rMlTcW3dU+ooF_(B z0iX6;3&=}$vVFj6J_k$}s_2bWN4fd{$Sqc+<)MMfvXq|Bb*ER8PNsi#=of%E3Mycw3!$@sq?D z-wJ9Djy$5|uBz1R&tTNgzj$KK349Ob8&pqV0Z`S&nV!x;ySRgIj1_H3qCVBIJUEKT zN>%5!OtSO&N;;}*j328aS1WQ6Q1FhQo+12?{f_xu(Hmm{gk$lk>X=Pb;}`pc7gXe~ za4@jawVhd-mNta??el;|lFy~8+O#H7jih@zdk%We!9KJiiJJjeQb#LHPLyXAdA#V& zDHkmMRL}_=Z&XfKWsc+%1U$`QE)7{_C)HJY&!Hvhr?z zds(umIx5nD&>+fD4ond^+Ha{P&}SU|d}?jykRy*nHW;i(Vj;M&d}A2*5U#PiI|?fC zH01lmPIjyW4jAJc#y4KJ>$cxf=*a~&AnaiF68xQr7$(my0=ciz)nylYL18V#Rd;>l zi1|9ck5eDssOn|*>J|T8%ryn4l{mc{-Uv*Y9s()5^4l;aAl#ivb{4($P*Ht6`=p82 zquwpP9%c`{wm6rUa$)hqZcR%Ytp3cet8A0xLl%J#FwUu^uDU2`Ty^)7jOT%}3xo}G zQ2HE|v$H+zPnT+-q+z(eHOt>ok#q5*dfVZGkP%1EFDJNA#yD%HyZr@6<*N(_xe};4 z+LB(|`Ea?0${I+|_Ow6kD2>3*a)k`D2S?!YgG~VzgDZ2J!C3Qb%|9h|e> z4lYz8{bcTiqpd*wFMzMOZu`(=lMqHdU6xR85G` zX4j8em|OMl?^Vo4r3?eqHO9|y#N5m9fXM#rK=cy3yYpw2c2xPhE4t)JOLLvz-!9`- z#*5;}1^cf8tQ4L-KEsjbs3Je27Sn&+VHYajvv-ZZo%O9*ubg`OemrNN2Y%JeROsCngvr8U6^2W$*D$l8R*$miKbEzyg{sj5F_ zIP%TOO0Gp+@UCU{q&-_vV~MBdt*QE1*#ki75E8R#@PDReq&Lp9tB3HGRKq+v Date: Fri, 15 Dec 2017 19:30:35 +0100 Subject: [PATCH 2/4] Add missing src/integration/impl/circleci for the CircleCI integration Signed-off-by: MTRNord --- src/integration/impl/circleci/CircleCiBot.js | 53 +++++++++ .../impl/circleci/CircleCiFactory.js | 20 ++++ .../impl/circleci/StubbedCircleCiBackbone.js | 63 ++++++++++ .../impl/circleci/VectorCircleCiBackbone.js | 108 ++++++++++++++++++ src/integration/impl/index.js | 2 + 5 files changed, 246 insertions(+) create mode 100644 src/integration/impl/circleci/CircleCiBot.js create mode 100644 src/integration/impl/circleci/CircleCiFactory.js create mode 100644 src/integration/impl/circleci/StubbedCircleCiBackbone.js create mode 100644 src/integration/impl/circleci/VectorCircleCiBackbone.js diff --git a/src/integration/impl/circleci/CircleCiBot.js b/src/integration/impl/circleci/CircleCiBot.js new file mode 100644 index 0000000..0a70bfd --- /dev/null +++ b/src/integration/impl/circleci/CircleCiBot.js @@ -0,0 +1,53 @@ +var ComplexBot = require("../../generic_types/ComplexBot"); + +/** + * Represents a CircleCI bot + */ +class CircleCiBot extends ComplexBot { + + /** + * Creates a new CircleCI bot + * @param botConfig the bot configuration + * @param backbone the backbone powering this bot + */ + constructor(botConfig, backbone) { + super(botConfig); + this._backbone = backbone; + } + + /*override*/ + getUserId() { + return this._backbone.getUserId(); + } + + /*override*/ + getState() { + var response = { + repoTemplates: [], + immutableRepoTemplates: [], + webhookUrl: "" + }; + return this._backbone.getRepos().then(templates => { + response.repoTemplates = templates; + return this._backbone.getImmutableRepos(); + }).then(immutable => { + response.immutableRepoTemplates = immutable; + return this._backbone.getWebhookUrl(); + }).then(url => { + response.webhookUrl = url; + return response; + }); + } + + /*override*/ + removeFromRoom(roomId) { + return this._backbone.removeFromRoom(roomId); + } + + /*override*/ + updateState(newState) { + return this._backbone.setRepos(newState.repoTemplates).then(() => this.getState()); + } +} + +module.exports = CircleCiBot; \ No newline at end of file diff --git a/src/integration/impl/circleci/CircleCiFactory.js b/src/integration/impl/circleci/CircleCiFactory.js new file mode 100644 index 0000000..c3e7fa7 --- /dev/null +++ b/src/integration/impl/circleci/CircleCiFactory.js @@ -0,0 +1,20 @@ +var CircleCiBot = require("./CircleCiBot"); +var VectorCircleCiBackbone = require("./VectorCircleCiBackbone"); +var UpstreamConfiguration = require("../../../UpstreamConfiguration"); + +var factory = (db, integrationConfig, roomId, scalarToken) => { + factory.validateConfig(integrationConfig); + + return db.getUpstreamToken(scalarToken).then(upstreamToken => { + var backbone = new VectorCircleCiBackbone(roomId, upstreamToken); + return new CircleCiBot(integrationConfig, backbone); + }); +}; + +factory.validateConfig = (integrationConfig) => { + if (!integrationConfig.upstream) throw new Error("Unsupported configuration"); + if (integrationConfig.upstream.type !== "vector") throw new Error("Unsupported upstream"); + if (!UpstreamConfiguration.hasUpstream("vector")) throw new Error("Vector upstream not specified"); +}; + +module.exports = factory; \ No newline at end of file diff --git a/src/integration/impl/circleci/StubbedCircleCiBackbone.js b/src/integration/impl/circleci/StubbedCircleCiBackbone.js new file mode 100644 index 0000000..d95255b --- /dev/null +++ b/src/integration/impl/circleci/StubbedCircleCiBackbone.js @@ -0,0 +1,63 @@ +/** + * Stubbed/placeholder CircleCI backbone + */ +class StubbedCircleCiBackbone { + + /** + * Creates a new stubbed RSS backbone + */ + constructor() { + } + + /** + * Gets the user ID for this backbone + * @returns {Promise} resolves to the user ID + */ + getUserId() { + throw new Error("Not implemented"); + } + + /** + * Gets the repository templates for this backbone + * @returns {Promise<{repoKey:string,template:string}[]>} resolves to the collection of repositories and their templates + */ + getRepos() { + throw new Error("Not implemented"); + } + + /** + * Gets the immutable repository templates for this backbone (set by other users) + * @returns {Promise<{repoKey:string,template:string,ownerId:string}[]>} resolves to the collection of repositories and their templates + */ + getImmutableRepos() { + throw new Error("Not implemented"); + } + + /** + * Sets the new repository templates for this backbone + * @param {{repoKey:string,template:string}[]} newRepos the new templates for the repositories + * @returns {Promise<>} resolves when complete + */ + setRepos(newRepos) { + throw new Error("Not implemented"); + } + + /** + * Gets the webhook url for this backbone + * @returns {Promise} resolves to the webhook URL + */ + getWebhookUrl() { + throw new Error("Not implemented"); + } + + /** + * Removes the bot from the given room + * @param {string} roomId the room ID to remove the bot from + * @returns {Promise<>} resolves when completed + */ + removeFromRoom(roomId) { + throw new Error("Not implemented"); + } +} + +module.exports = StubbedCircleCiBackbone; \ No newline at end of file diff --git a/src/integration/impl/circleci/VectorCircleCiBackbone.js b/src/integration/impl/circleci/VectorCircleCiBackbone.js new file mode 100644 index 0000000..307ea11 --- /dev/null +++ b/src/integration/impl/circleci/VectorCircleCiBackbone.js @@ -0,0 +1,108 @@ +var StubbedCircleCiBackbone = require("./StubbedCircleCiBackbone"); +var VectorScalarClient = require("../../../scalar/VectorScalarClient"); +var _ = require("lodash"); +var log = require("../../../util/LogService"); + +/** + * Backbone for Travis CI bots running on vector.im through scalar + */ +class VectorCircleCiBackbone extends StubbedCircleCiBackbone { + + /** + * Creates a new Vector CircleCI backbone + * @param {string} roomId the room ID to manage + * @param {string} upstreamScalarToken the vector scalar token + */ + constructor(roomId, upstreamScalarToken) { + super(); + this._roomId = roomId; + this._scalarToken = upstreamScalarToken; + this._info = null; + this._otherTemplates = []; + } + + /*override*/ + getUserId() { + return (this._info ? Promise.resolve() : this._getInfo()).then(() => { + return this._info.bot_user_id; + }); + } + + /*override*/ + getRepos() { + return (this._info ? Promise.resolve() : this._getInfo()).then(() => { + if (this._info.integrations.length == 0) return []; + + var rooms = _.keys(this._info.integrations[0].config.rooms); + if (rooms.indexOf(this._roomId) === -1) return []; + + var repos = _.keys(this._info.integrations[0].config.rooms[this._roomId].repos); + return _.map(repos, r => { + return {repoKey: r, template: this._info.integrations[0].config.rooms[this._roomId].repos[r].template}; + }); + }); + } + + /*override*/ + getImmutableRepos() { + return (this._info ? Promise.resolve() : this._getInfo()).then(() => { + return this._otherTemplates; + }); + } + + /*override*/ + setRepos(newRepos) { + var config = {}; + config[this._roomId] = {repos: {}}; + for (var repo of newRepos) config[this._roomId].repos[repo.repoKey] = {template: repo.template}; + + return VectorScalarClient.configureIntegration("circleci", this._scalarToken, { + rooms: config + }); + } + + /*override*/ + getWebhookUrl() { + // string + return (this._info ? Promise.resolve() : this._getInfo()).then(() => { + if (this._info.integrations.length == 0) return ""; + return this._info.integrations[0].config.webhook_url; + }); + } + + _getInfo() { + return VectorScalarClient.getIntegrationsForRoom(this._roomId, this._scalarToken).then(integrations => { + this._otherTemplates = []; + for (var integration of integrations) { + if (integration.self) continue; // skip - we're not looking for ones we know about + if (integration.type == "circleci") { + var roomIds = _.keys(integration.config.rooms); + if (roomIds.length === 0) continue; + if (roomIds.length !== 1) log.warn("VectorCircleCiBackbone", "Expected 1 room but found " + roomIds.length); + + var roomConfig = integration.config.rooms[roomIds[0]]; + var repositories = _.keys(roomConfig.repos); + + for (var repo of repositories) { + this._otherTemplates.push({ + repoKey: repo, + template: roomConfig.repos[repo].template, + ownerId: integration.user_id + }); + } + } + } + + return VectorScalarClient.getIntegration("circleci", this._roomId, this._scalarToken); + }).then(info => { + this._info = info; + }); + } + + /*override*/ + removeFromRoom(roomId) { + return VectorScalarClient.removeIntegration("circleci", roomId, this._scalarToken); + } +} + +module.exports = VectorCircleCiBackbone; \ No newline at end of file diff --git a/src/integration/impl/index.js b/src/integration/impl/index.js index d3be9ea..92d7e9b 100644 --- a/src/integration/impl/index.js +++ b/src/integration/impl/index.js @@ -4,12 +4,14 @@ var SimpleBotFactory = require("./simple_bot/SimpleBotFactory"); var RSSFactory = require("./rss/RSSFactory"); var IRCFactory = require("./irc/IRCFactory"); var TravisCiFactory = require("./travisci/TravisCiFactory"); +var CircleCiFactory = require("./circleci/CircleCiFactory"); var SimpleWidgetFactory = require("./simple_widget/SimpleWidgetFactory"); var mapping = { "complex-bot": { "rss": RSSFactory, "travisci": TravisCiFactory, + "circleci": CircleCiFactory, }, "bridge": { "irc": IRCFactory, From 6079cb9ce699fddbe25e1c17e33ac135ef88eefe Mon Sep 17 00:00:00 2001 From: MTRNord Date: Fri, 15 Dec 2017 20:01:40 +0100 Subject: [PATCH 3/4] Fix wrong names in circleCI impl Signed-off-by: MTRNord --- src/integration/impl/circleci/StubbedCircleCiBackbone.js | 2 +- src/integration/impl/circleci/VectorCircleCiBackbone.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/integration/impl/circleci/StubbedCircleCiBackbone.js b/src/integration/impl/circleci/StubbedCircleCiBackbone.js index d95255b..0a454db 100644 --- a/src/integration/impl/circleci/StubbedCircleCiBackbone.js +++ b/src/integration/impl/circleci/StubbedCircleCiBackbone.js @@ -4,7 +4,7 @@ class StubbedCircleCiBackbone { /** - * Creates a new stubbed RSS backbone + * Creates a new stubbed CircleCI backbone */ constructor() { } diff --git a/src/integration/impl/circleci/VectorCircleCiBackbone.js b/src/integration/impl/circleci/VectorCircleCiBackbone.js index 307ea11..9b3ee4a 100644 --- a/src/integration/impl/circleci/VectorCircleCiBackbone.js +++ b/src/integration/impl/circleci/VectorCircleCiBackbone.js @@ -4,7 +4,7 @@ var _ = require("lodash"); var log = require("../../../util/LogService"); /** - * Backbone for Travis CI bots running on vector.im through scalar + * Backbone for CircleCI bots running on vector.im through scalar */ class VectorCircleCiBackbone extends StubbedCircleCiBackbone { From fcee6f2078833abc2ad7fc9f9bb04f2cc6acc1d6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 15 Dec 2017 12:06:34 -0700 Subject: [PATCH 4/4] Disable circleci by default for now until Scalar supports it --- config/integrations/circleci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/integrations/circleci.yaml b/config/integrations/circleci.yaml index 31de701..f0941c5 100644 --- a/config/integrations/circleci.yaml +++ b/config/integrations/circleci.yaml @@ -1,6 +1,6 @@ type: "complex-bot" integrationType: "circleci" -enabled: true +enabled: false # disabled because the API is considered unstable/inoperable. Use at your own risk! name: "CircleCI" about: "Sends CircleCI build results into the room" avatar: "img/avatars/circleci.png"