@spotify/backstage-plugin-soundcheck-backend-module-github 0.6.6 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @spotify/backstage-plugin-soundcheck-backend-module-github
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Remove support for the legacy backend system.
8
+
9
+ ### Patch Changes
10
+
11
+ - Update to Backstage `v1.35.0`
12
+ - Updated dependencies
13
+ - @spotify/backstage-plugin-soundcheck-common@0.15.0
14
+ - @spotify/backstage-plugin-soundcheck-node@0.9.0
15
+
3
16
  ## 0.6.6
4
17
 
5
18
  ### Patch Changes
@@ -1,2 +1,2 @@
1
- "use strict";var C=require("@backstage/catalog-model"),g=require("@backstage/integration"),E=require("@octokit/rest"),a=require("@spotify/backstage-plugin-soundcheck-common"),v=require("@spotify/backstage-plugin-soundcheck-node"),F=require("git-url-parse"),S=require("zod-to-json-schema"),b=require("../extractors/BranchProtectionsFactExtractor.cjs.js"),x=require("../extractors/BranchRulesFactExtractor.cjs.js"),R=require("../extractors/config/GithubFactCollectorSchema.cjs.js"),q=require("../extractors/ExtractorService.cjs.js"),D=require("../extractors/helper/BranchHelper.cjs.js"),P=require("../extractors/RepositoryDetailsFactExtractor.cjs.js"),k=require("../extractors/RepositoryLanguagesFactExtractor.cjs.js"),G=require("../extractors/store/GithubExtractorsStore.cjs.js");function d(s){return s&&typeof s=="object"&&"default"in s?s:{default:s}}var U=d(F),B=d(S);class u{static ID="github";#r;#a;#i;#e;#t;static create(t,r,i){return new u(t,r,i)}id=u.ID;name="GitHub";description="Collects facts about your GitHub repositories.";constructor(t,r,i){this.#r=r.child({target:this.id}),this.#a=g.ScmIntegrations.fromConfig(t),this.#i=g.DefaultGithubCredentialsProvider.fromIntegrations(this.#a),this.#e=q.ExtractorService.create({logger:this.#r,cache:i.getClient(),branchHelper:D.BranchHelper.create(this.#r,i.getClient({defaultTtl:60*60*1e3})),factories:[b.BranchProtectionsFactExtractor.factory,x.BranchRulesFactExtractor.factory,P.RepositoryDetailsFactExtractor.factory,k.RepositoryLanguagesFactExtractor.factory]}),this.#t=G.GithubExtractorsStore.create(this.#r)}async collect(t,r){const i=r?.factRefs??this.#t.getExtractorConfigs().map(e=>a.getFactRef(this.id,e));return Promise.all(t.filter(e=>a.isScmEntity(e)).map(async e=>{const o=C.stringifyEntityRef(e),l=a.getEntityScmUrl(e),y=U.default(l),f=await this.getOctokit(l);return f?Promise.all(i.map(async n=>{const h=a.parseFactRef(n,{defaultSource:this.id,defaultScope:a.DEFAULT_SCOPE}),p=this.#t.getExtractorConfig(h.name),m=!!r?.refresh?.map(c=>a.stringifyFactRef(c))?.includes(a.stringifyFactRef(n));return this.#e.extract(p,h.scope,y,f,m).then(c=>{if(c!==void 0)return a.buildFact(o,n,c)}).catch(c=>{if(c instanceof v.RateLimitError)throw c;return this.#r.error(`Failed to collect ${a.stringifyFactRef(n)} fact data for ${o} entity: ${c}`),a.buildCollectionError(o,n,c)})})):Promise.resolve()})).then(e=>e.flat().filter(o=>!!o))}async getOctokit(t){try{const{token:r}=await this.#i.getCredentials({url:t}),i=this.#a.github.byUrl(t);return new E.Octokit({auth:r,baseUrl:i?.config.apiBaseUrl})}catch(r){this.#r.warn(`Skipping Github fact collection for url ${t}: ${r}`);return}}async getCollectionConfigs(){return a.buildCollectionConfigs(this.id,this.#t.getExtractorConfigs())}async getFactNames(){const t=this.#e.listFactTypes(),r=this.#t.getExtractorConfigs();return t.flatMap(i=>r.filter(e=>e.type===i).map(e=>e.factName??e.type)??i)}async getDataSchema(t){const r=a.parseFactRef(t,{defaultSource:this.id,defaultScope:a.DEFAULT_SCOPE}),i=this.#t.getExtractorConfigs().find(e=>{const o=a.parseFactRef(a.getFactRef(this.id,e));return r.source===o.source&&r.name===o.name});if(i)return this.#e.getDataSchema(i)}async getConfig(){return this.#t.getConfig()}async setConfig(t){this.#t.setConfig(t)}async getConfigSchema(){return JSON.stringify(B.default(R.GithubFactCollectorSchema))}}exports.GithubFactCollector=u;
1
+ "use strict";var E=require("@backstage/catalog-model"),g=require("@backstage/integration"),C=require("@octokit/rest"),a=require("@spotify/backstage-plugin-soundcheck-common"),F=require("@spotify/backstage-plugin-soundcheck-node"),v=require("git-url-parse"),S=require("zod-to-json-schema"),b=require("../extractors/BranchProtectionsFactExtractor.cjs.js"),x=require("../extractors/BranchRulesFactExtractor.cjs.js"),R=require("../extractors/config/GithubFactCollectorSchema.cjs.js"),q=require("../extractors/ExtractorService.cjs.js"),D=require("../extractors/helper/BranchHelper.cjs.js"),G=require("../extractors/RepositoryDetailsFactExtractor.cjs.js"),P=require("../extractors/RepositoryLanguagesFactExtractor.cjs.js"),k=require("../extractors/store/GithubExtractorsStore.cjs.js");function d(s){return s&&typeof s=="object"&&"default"in s?s:{default:s}}var U=d(v),w=d(S);class u{static ID="github";#r;#a;#i;#e;#t;static create(r,t,i){return new u(r,t,i)}id=u.ID;name="GitHub";description="Collects facts about your GitHub repositories.";constructor(r,t,i){this.#r=t.child({target:this.id}),this.#a=g.ScmIntegrations.fromConfig(r),this.#i=g.DefaultGithubCredentialsProvider.fromIntegrations(this.#a),this.#e=q.ExtractorService.create({logger:t,cache:i,branchHelper:D.BranchHelper.create(this.#r,i.withOptions({defaultTtl:60*60*1e3})),factories:[b.BranchProtectionsFactExtractor.factory,x.BranchRulesFactExtractor.factory,G.RepositoryDetailsFactExtractor.factory,P.RepositoryLanguagesFactExtractor.factory]}),this.#t=k.GithubExtractorsStore.create(this.#r)}async collect(r,t){const i=t?.factRefs??this.#t.getExtractorConfigs().map(e=>a.getFactRef(this.id,e));return Promise.all(r.filter(e=>a.isScmEntity(e)).map(async e=>{const o=E.stringifyEntityRef(e),l=a.getEntityScmUrl(e),y=U.default(l),f=await this.getOctokit(l);return f?Promise.all(i.map(async n=>{const h=a.parseFactRef(n,{defaultSource:this.id,defaultScope:a.DEFAULT_SCOPE}),p=this.#t.getExtractorConfig(h.name),m=!!t?.refresh?.map(c=>a.stringifyFactRef(c))?.includes(a.stringifyFactRef(n));return this.#e.extract(p,h.scope,y,f,m).then(c=>{if(c!==void 0)return a.buildFact(o,n,c)}).catch(c=>{if(c instanceof F.RateLimitError)throw c;return this.#r.error(`Failed to collect ${a.stringifyFactRef(n)} fact data for ${o} entity: ${c}`),a.buildCollectionError(o,n,c)})})):Promise.resolve()})).then(e=>e.flat().filter(o=>!!o))}async getOctokit(r){try{const{token:t}=await this.#i.getCredentials({url:r}),i=this.#a.github.byUrl(r);return new C.Octokit({auth:t,baseUrl:i?.config.apiBaseUrl})}catch(t){this.#r.warn(`Skipping Github fact collection for url ${r}: ${t}`);return}}async getCollectionConfigs(){return a.buildCollectionConfigs(this.id,this.#t.getExtractorConfigs())}async getFactNames(){const r=this.#e.listFactTypes(),t=this.#t.getExtractorConfigs();return r.flatMap(i=>t.filter(e=>e.type===i).map(e=>e.factName??e.type)??i)}async getDataSchema(r){const t=a.parseFactRef(r,{defaultSource:this.id,defaultScope:a.DEFAULT_SCOPE}),i=this.#t.getExtractorConfigs().find(e=>{const o=a.parseFactRef(a.getFactRef(this.id,e));return t.source===o.source&&t.name===o.name});if(i)return this.#e.getDataSchema(i)}async getConfig(){return this.#t.getConfig()}async setConfig(r){this.#t.setConfig(r)}async getConfigSchema(){return JSON.stringify(w.default(R.GithubFactCollectorSchema))}}exports.GithubFactCollector=u;
2
2
  //# sourceMappingURL=GithubFactCollector.cjs.js.map
@@ -1,2 +1,2 @@
1
- "use strict";var w=require("@spotify/backstage-plugin-soundcheck-common"),n=require("./helper/util.cjs.js"),y=require("./schema/branch_rules.json.cjs.js"),E=require("./utils.cjs.js");class c{static TYPE="BranchRules";#t;#e;#r;type=c.TYPE;static factory=({logger:r,cache:a,branchHelper:e})=>{const s=new c(r,a,e);return{predicate:o=>o.type===s.type,extractor:s}};constructor(r,a,e){this.#t=r,this.#e=a,this.#r=e}async extract(r,a,e,s,o){const h=[],g={owner:e.owner,repo:e.name,branch:await this.#a(a,e,s)},f=100;let p=0,i=!0;for(;i;){const u=`github:branch_rules:${e.owner}:${e.name}:${a}:${++p}`;try{const t=await s.rest.repos.getBranchRules({...g,per_page:f,page:p,headers:o?void 0:await E.getCacheHeader(this.#e,u)});t.headers?.link?.includes('rel="next"')||(i=!1),await this.#e.set(u,{etag:t.headers?.etag,lastModified:t.headers?.date,hasNext:i,data:t.data}),h.push(...t.data)}catch(t){if(n.isNotModifiedError(t)){const l=await this.#e.get(u);if(l){h.push(...l.data),i=l.hasNext;continue}else return}if(n.isNotFoundError(t))return{rules:[]};const d=`[BranchRules] fact extraction failed with: ${n.buildOctokitErrorMessage(t)}. Request parameters: ${JSON.stringify(g)}`;throw n.handleRateLimitError(t,d),this.#t.error(d),new Error(d)}}return{rules:h}}async#a(r,a,e){return r!==w.DEFAULT_SCOPE?r:this.#r.getDefaultBranch(a,e)}getDataSchema(r){return JSON.stringify(y.default)}}exports.BranchRulesFactExtractor=c;
1
+ "use strict";var w=require("@spotify/backstage-plugin-soundcheck-common"),n=require("./helper/util.cjs.js"),y=require("./schema/branch_rules.json.cjs.js"),E=require("./utils.cjs.js");class c{static TYPE="BranchRules";#t;#e;#r;type=c.TYPE;static factory=({logger:r,cache:a,branchHelper:e})=>{const s=new c(r,a,e);return{predicate:o=>o.type===s.type,extractor:s}};constructor(r,a,e){this.#t=r,this.#e=a,this.#r=e}async extract(r,a,e,s,o){const h=[],g={owner:e.owner,repo:e.name,branch:await this.#a(a,e,s)},p=100;let f=0,i=!0;for(;i;){const u=`github:branch_rules:${e.owner}:${e.name}:${a}:${++f}`;try{const t=await s.rest.repos.getBranchRules({...g,per_page:p,page:f,headers:o?void 0:await E.getCacheHeader(this.#e,u)});t.headers?.link?.includes('rel="next"')||(i=!1),await this.#e.set(u,{etag:t.headers?.etag,lastModified:t.headers?.date,hasNext:i,data:t.data}),h.push(...t.data)}catch(t){if(n.isNotModifiedError(t)){const d=await this.#e.get(u);if(d){h.push(...d.data),i=d.hasNext;continue}else return}if(n.isNotFoundError(t))return{rules:[]};const l=`[BranchRules] fact extraction failed with: ${n.buildOctokitErrorMessage(t)}. Request parameters: ${JSON.stringify(g)}`;throw n.handleRateLimitError(t,l),this.#t.error(l),new Error(l)}}return{rules:h}}async#a(r,a,e){return r!==w.DEFAULT_SCOPE?r:this.#r.getDefaultBranch(a,e)}getDataSchema(r){return JSON.stringify(y.default)}}exports.BranchRulesFactExtractor=c;
2
2
  //# sourceMappingURL=BranchRulesFactExtractor.cjs.js.map
@@ -1,2 +1,2 @@
1
- "use strict";var i=require("./helper/util.cjs.js"),g=require("./schema/repository_details.json.cjs.js"),y=require("./utils.cjs.js");class s{static TYPE="RepositoryDetails";#e;#t;type=s.TYPE;static factory=({logger:r,cache:a})=>{const e=new s(r,a);return{predicate:o=>o.type===e.type,extractor:e}};constructor(r,a){this.#e=r,this.#t=a}async extract(r,a,e,o,u){const c=`github:repository_details:${e.owner}:${e.name}`,l=u?void 0:await y.getCacheHeader(this.#t,c),h={owner:e.owner,repo:e.name,headers:l};try{const t=await o.rest.repos.get(h);return await this.#t.set(c,{etag:t.headers?.etag,lastModified:t.headers?.date,data:t.data}),t.data}catch(t){if(i.isNotModifiedError(t)){const d=await this.#t.get(c);return!d||!("data"in d)?void 0:d.data}if(i.isNotFoundError(t))return{};const n=`[RepositoryDetails] fact extraction failed with: ${i.buildOctokitErrorMessage(t)}. Request parameters: ${JSON.stringify(h)}`;throw i.handleRateLimitError(t,n),this.#e.error(n),new Error(n)}}getDataSchema(r){return JSON.stringify(g.default)}}exports.RepositoryDetailsFactExtractor=s;
1
+ "use strict";var i=require("./helper/util.cjs.js"),g=require("./schema/repository_details.json.cjs.js"),y=require("./utils.cjs.js");class s{static TYPE="RepositoryDetails";#e;#t;type=s.TYPE;static factory=({logger:r,cache:a})=>{const e=new s(r,a);return{predicate:o=>o.type===e.type,extractor:e}};constructor(r,a){this.#e=r,this.#t=a}async extract(r,a,e,o,u){const c=`github:repository_details:${e.owner}:${e.name}`,l=u?void 0:await y.getCacheHeader(this.#t,c),h={owner:e.owner,repo:e.name,headers:l};try{const t=await o.rest.repos.get(h);return await this.#t.set(c,{etag:t.headers?.etag,lastModified:t.headers?.date,data:t.data}),t.data}catch(t){if(i.isNotModifiedError(t)){const n=await this.#t.get(c);return!n||!("data"in n)?void 0:n.data}if(i.isNotFoundError(t))return{};const d=`[RepositoryDetails] fact extraction failed with: ${i.buildOctokitErrorMessage(t)}. Request parameters: ${JSON.stringify(h)}`;throw i.handleRateLimitError(t,d),this.#e.error(d),new Error(d)}}getDataSchema(r){return JSON.stringify(g.default)}}exports.RepositoryDetailsFactExtractor=s;
2
2
  //# sourceMappingURL=RepositoryDetailsFactExtractor.cjs.js.map
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./collector/GithubFactCollector.cjs.js"),t=require("./service/GithubFactCollectorModule.cjs.js"),r=require("./templates.cjs.js");exports.GithubFactCollector=e.GithubFactCollector,exports.default=t.default,exports.githubCheckTemplates=r.githubCheckTemplates;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("./service/GithubFactCollectorModule.cjs.js"),t=require("./templates.cjs.js");exports.default=e.default,exports.githubCheckTemplates=t.githubCheckTemplates;
2
2
  //# sourceMappingURL=index.cjs.js.map
package/dist/index.d.ts CHANGED
@@ -1,44 +1,5 @@
1
- import { PluginCacheManager } from '@backstage/backend-common';
2
- import { Entity } from '@backstage/catalog-model';
3
- import { Config } from '@backstage/config';
4
- import { JsonValue } from '@backstage/types';
5
- import { FactRef, Fact, CollectionError, CollectionConfig } from '@spotify/backstage-plugin-soundcheck-common';
6
- import { ConfigurableFactCollector, CheckTemplate } from '@spotify/backstage-plugin-soundcheck-node';
7
- import { Logger } from 'winston';
8
1
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
9
-
10
- /**
11
- * Soundcheck 3rd party integration - Github.
12
- *
13
- * @public
14
- */
15
- declare class GithubFactCollector implements ConfigurableFactCollector {
16
- #private;
17
- /**
18
- * Source identifier used by the {@link GithubFactCollector}.
19
- */
20
- static ID: string;
21
- static create(config: Config, logger: Logger, cache: PluginCacheManager): GithubFactCollector;
22
- /** {@inheritDoc @spotify/backstage-plugin-soundcheck-node#FactCollector.id} */
23
- id: string;
24
- name: string;
25
- description: string;
26
- private constructor();
27
- /** {@inheritDoc @spotify/backstage-plugin-soundcheck-node#FactCollector.collect} */
28
- collect(entities: Entity[], params?: {
29
- factRefs?: FactRef[];
30
- refresh?: FactRef[];
31
- }): Promise<(Fact | CollectionError)[]>;
32
- /** {@inheritDoc @spotify/backstage-plugin-soundcheck-node#FactCollector.getCollectionConfigs} */
33
- getCollectionConfigs(): Promise<CollectionConfig[]>;
34
- /** {@inheritDoc @spotify/backstage-plugin-soundcheck-node#FactCollector.getFactNames} */
35
- getFactNames(): Promise<string[]>;
36
- /** {@inheritDoc @spotify/backstage-plugin-soundcheck-node#FactCollector.getDataSchema} */
37
- getDataSchema(factRef: FactRef): Promise<string | undefined>;
38
- getConfig(): Promise<JsonValue | undefined>;
39
- setConfig(config: JsonValue): Promise<void>;
40
- getConfigSchema(): Promise<string>;
41
- }
2
+ import { CheckTemplate } from '@spotify/backstage-plugin-soundcheck-node';
42
3
 
43
4
  /** @public */
44
5
  declare const githubSoundcheckModule: _backstage_backend_plugin_api.BackendFeature;
@@ -50,4 +11,4 @@ declare const githubSoundcheckModule: _backstage_backend_plugin_api.BackendFeatu
50
11
  */
51
12
  declare function githubCheckTemplates(): CheckTemplate[];
52
13
 
53
- export { GithubFactCollector, githubSoundcheckModule as default, githubCheckTemplates };
14
+ export { githubSoundcheckModule as default, githubCheckTemplates };
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var c=require("@backstage/backend-common"),e=require("@backstage/backend-plugin-api"),t=require("@spotify/backstage-plugin-soundcheck-node"),s=require("../collector/GithubFactCollector.cjs.js"),g=require("../templates.cjs.js");const u=e.createBackendModule({pluginId:"soundcheck",moduleId:"github",register(o){o.registerInit({deps:{cache:e.coreServices.cache,config:e.coreServices.rootConfig,logger:e.coreServices.logger,collectorsExtension:t.factCollectionExtensionPoint,templatesExtension:t.checkTemplateExtensionPoint},async init({cache:r,config:i,logger:n,collectorsExtension:a,templatesExtension:l}){a.addFactCollector(s.GithubFactCollector.create(i,c.loggerToWinstonLogger(n),c.cacheToPluginCacheManager(r))),l.addCheckTemplates(...g.githubCheckTemplates())}})}});exports.default=u;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@backstage/backend-plugin-api"),t=require("@spotify/backstage-plugin-soundcheck-node"),a=require("../collector/GithubFactCollector.cjs.js"),s=require("../templates.cjs.js");const u=e.createBackendModule({pluginId:"soundcheck",moduleId:"github",register(c){c.registerInit({deps:{cache:e.coreServices.cache,config:e.coreServices.rootConfig,logger:e.coreServices.logger,collectorsExtension:t.factCollectionExtensionPoint,templatesExtension:t.checkTemplateExtensionPoint},async init({cache:o,config:r,logger:i,collectorsExtension:n,templatesExtension:l}){n.addFactCollector(a.GithubFactCollector.create(r,i,o)),l.addCheckTemplates(...s.githubCheckTemplates())}})}});exports.default=u;
2
2
  //# sourceMappingURL=GithubFactCollectorModule.cjs.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spotify/backstage-plugin-soundcheck-backend-module-github",
3
3
  "description": "Soundcheck 3rd party integration with Github",
4
- "version": "0.6.6",
4
+ "version": "0.7.0",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "homepage": "https://backstage.spotify.com",
7
7
  "main": "dist/index.cjs.js",
@@ -24,25 +24,24 @@
24
24
  "postpack": "backstage-cli package postpack"
25
25
  },
26
26
  "devDependencies": {
27
- "@backstage/backend-test-utils": "^1.2.0",
28
- "@backstage/cli": "^0.29.4",
29
- "@spotify/backstage-plugin-soundcheck-backend": "^0.17.10",
27
+ "@backstage/backend-test-utils": "^1.2.1",
28
+ "@backstage/cli": "^0.29.5",
29
+ "@spotify/backstage-plugin-soundcheck-backend": "^0.18.0",
30
30
  "@types/git-url-parse": "^9.0.0",
31
31
  "@types/luxon": "^3.0.1",
32
32
  "supertest": "^7.0.0"
33
33
  },
34
34
  "dependencies": {
35
- "@backstage/backend-common": "^0.25.0",
36
- "@backstage/backend-plugin-api": "^1.1.0",
37
- "@backstage/catalog-model": "^1.7.2",
38
- "@backstage/config": "^1.3.1",
39
- "@backstage/errors": "^1.2.6",
40
- "@backstage/integration": "^1.16.0",
41
- "@backstage/types": "^1.2.0",
35
+ "@backstage/backend-plugin-api": "^1.1.1",
36
+ "@backstage/catalog-model": "^1.7.3",
37
+ "@backstage/config": "^1.3.2",
38
+ "@backstage/errors": "^1.2.7",
39
+ "@backstage/integration": "^1.16.1",
40
+ "@backstage/types": "^1.2.1",
42
41
  "@octokit/request-error": "^5.0.0",
43
42
  "@octokit/rest": "^20.0.0",
44
- "@spotify/backstage-plugin-soundcheck-common": "^0.14.5",
45
- "@spotify/backstage-plugin-soundcheck-node": "^0.8.6",
43
+ "@spotify/backstage-plugin-soundcheck-common": "^0.15.0",
44
+ "@spotify/backstage-plugin-soundcheck-node": "^0.9.0",
46
45
  "git-url-parse": "^16.0.0",
47
46
  "lodash": "^4.17.21",
48
47
  "luxon": "^3.1.1",