Skip to content

Commit

Permalink
refactor(azure-bicep-resource): Refactor schema usage (#21402)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
  • Loading branch information
zharinov and viceice committed Apr 11, 2023
1 parent 00c8f90 commit 7fdb8e2
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 98 deletions.
72 changes: 36 additions & 36 deletions lib/modules/datasource/azure-bicep-resource/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ describe('modules/datasource/azure-bicep-resource/index', () => {
.reply(
200,
codeBlock`
{
"Resources": {},
"Functions": {}
}
`
{
"Resources": {},
"Functions": {}
}
`
);

const azureBicepResourceDatasource = new AzureBicepResourceDatasource();
Expand All @@ -35,26 +35,26 @@ describe('modules/datasource/azure-bicep-resource/index', () => {
.reply(
200,
codeBlock`
{
"Resources": {},
"Functions": {
"microsoft.billing/billingaccounts": {
"2019-10-01-preview": [
{
"RelativePath": "billing/microsoft.billing/2019-10-01-preview/types.json",
"Index": 307
}
],
"2020-05-01": [
{
"RelativePath": "billing/microsoft.billing/2020-05-01/types.json",
"Index": 287
}
]
{
"Resources": {},
"Functions": {
"microsoft.billing/billingaccounts": {
"2019-10-01-preview": [
{
"RelativePath": "billing/microsoft.billing/2019-10-01-preview/types.json",
"Index": 307
}
],
"2020-05-01": [
{
"RelativePath": "billing/microsoft.billing/2020-05-01/types.json",
"Index": 287
}
]
}
}
}
}
`
`
);

const azureBicepResourceDatasource = new AzureBicepResourceDatasource();
Expand Down Expand Up @@ -85,20 +85,20 @@ describe('modules/datasource/azure-bicep-resource/index', () => {
.reply(
200,
codeBlock`
{
"Resources": {
"Microsoft.Storage/storageAccounts@2015-05-01-preview": {
"RelativePath": "storage/microsoft.storage/2015-05-01-preview/types.json",
"Index": 31
{
"Resources": {
"Microsoft.Storage/storageAccounts@2015-05-01-preview": {
"RelativePath": "storage/microsoft.storage/2015-05-01-preview/types.json",
"Index": 31
},
"Microsoft.Storage/storageAccounts@2018-02-01": {
"RelativePath": "storage/microsoft.storage/2018-02-01/types.json",
"Index": 85
}
},
"Microsoft.Storage/storageAccounts@2018-02-01": {
"RelativePath": "storage/microsoft.storage/2018-02-01/types.json",
"Index": 85
}
},
"Functions": {}
}
`
"Functions": {}
}
`
);

const azureBicepResourceDatasource = new AzureBicepResourceDatasource();
Expand Down
65 changes: 23 additions & 42 deletions lib/modules/datasource/azure-bicep-resource/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { cache } from '../../../util/cache/package/decorator';
import * as azureRestApiVersioningApi from '../../versioning/azure-rest-api';
import { Datasource } from '../datasource';
import type { GetReleasesConfig, ReleaseResult } from '../types';
import { BicepTypeIndex } from './schema';
import { BicepResourceVersionIndex } from './schema';

const BICEP_TYPES_INDEX_URL =
'https://raw.githubusercontent.com/Azure/bicep-types-az/main/generated/index.json';
Expand All @@ -25,64 +25,45 @@ export class AzureBicepResourceDatasource extends Datasource {
super(AzureBicepResourceDatasource.id);
}

private getChangelogUrl(packageName: string): string {
const firstSlashIndex = packageName.indexOf('/');
const namespaceProvider = packageName.slice(0, firstSlashIndex);
const type = packageName.slice(firstSlashIndex + 1);
return `https://learn.microsoft.com/en-us/azure/templates/${namespaceProvider}/change-log/${type}`;
}

@cache({
namespace: `datasource-${AzureBicepResourceDatasource.id}`,
key: ({ packageName }: GetReleasesConfig) => `getReleases-${packageName}`,
})
async getReleases(
getReleasesConfig: GetReleasesConfig
): Promise<ReleaseResult | null> {
const { packageName } = getReleasesConfig;

const resourceVersionIndex = await this.getResourceVersionIndex();
const versions = resourceVersionIndex[packageName.toLowerCase()];

if (!versions) {
const packageName = getReleasesConfig.packageName.toLowerCase();
const versions = resourceVersionIndex[packageName];
if (!versions?.length) {
return null;
}

const firstSlashIndex = packageName.indexOf('/');
const namespaceProvider = packageName
.slice(0, firstSlashIndex)
.toLowerCase();
const type = packageName.slice(firstSlashIndex + 1).toLowerCase();

return {
releases: versions.map((version) => ({
version,
changelogUrl: `https://learn.microsoft.com/en-us/azure/templates/${namespaceProvider}/change-log/${type}#${version}`,
})),
};
const changelogUrl = this.getChangelogUrl(packageName);
const releases = versions.map((version) => ({
version,
changelogUrl: `${changelogUrl}#${version}`,
}));
return { releases };
}

@cache({
namespace: `datasource-${AzureBicepResourceDatasource.id}`,
key: 'getResourceVersionIndex',
ttlMinutes: 24 * 60,
})
async getResourceVersionIndex(): Promise<Record<string, string[]>> {
const res = await this.getBicepTypeIndex();

const releaseMap = new Map<string, string[]>();

for (const resourceReference of Object.keys(res.Resources)) {
const [type, version] = resourceReference.toLowerCase().split('@', 2);
const versions = releaseMap.get(type) ?? [];
versions.push(version);
releaseMap.set(type, versions);
}

for (const functionResource of Object.entries(res.Functions)) {
const [type, versionMap] = functionResource;
const versions = Object.keys(versionMap);
releaseMap.set(type, versions);
}

return Object.fromEntries(releaseMap);
}

private async getBicepTypeIndex(): Promise<BicepTypeIndex> {
const res = await this.http.getJson(BICEP_TYPES_INDEX_URL, BicepTypeIndex);
return res.body;
async getResourceVersionIndex(): Promise<BicepResourceVersionIndex> {
const { body } = await this.http.getJson(
BICEP_TYPES_INDEX_URL,
BicepResourceVersionIndex
);
return body;
}
}
60 changes: 40 additions & 20 deletions lib/modules/datasource/azure-bicep-resource/schema.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
import { z } from 'zod';

export const BicepTypeIndex = z.object({
Resources: z.record(
z.string(),
z.object({
RelativePath: z.string(),
Index: z.number(),
})
),
Functions: z.record(
z.string(),
z.record(
export const BicepResourceVersionIndex = z
.object({
Resources: z.record(
z.string(),
z.array(
z.object({
RelativePath: z.string(),
Index: z.number(),
})
z.object({
RelativePath: z.string(),
Index: z.number(),
})
),
Functions: z.record(
z.string(),
z.record(
z.string(),
z.array(
z.object({
RelativePath: z.string(),
Index: z.number(),
})
)
)
)
),
});
),
})
.transform(({ Resources, Functions }) => {
const releaseMap = new Map<string, string[]>();

for (const resourceReference of Object.keys(Resources)) {
const [type, version] = resourceReference.toLowerCase().split('@', 2);
const versions = releaseMap.get(type) ?? [];
versions.push(version);
releaseMap.set(type, versions);
}

for (const [type, versionMap] of Object.entries(Functions)) {
const versions = Object.keys(versionMap);
releaseMap.set(type, versions);
}

return Object.fromEntries(releaseMap);
});

export type BicepTypeIndex = z.infer<typeof BicepTypeIndex>;
export type BicepResourceVersionIndex = z.infer<
typeof BicepResourceVersionIndex
>;

0 comments on commit 7fdb8e2

Please sign in to comment.