Skip to content

Commit

Permalink
chore: store schema version inside package (#96)
Browse files Browse the repository at this point in the history
(Take 2 of #62).

Currently, the schema version espoused by this package is the package version itself (i.e., the version of its own `package.json`). Move this version to a resource file that maintained inside the package and is bumped explicitly.

In a projen (mono)repo, all packages have version 0.0.0. At development time, the Cloud Assembly Schema has to know its own version, for various versioning checks. It can’t get it from the package version (which is 0.0.0, so it needs to get it elsewhere, which will be schema.version.json).

Closes #62.
  • Loading branch information
rix0rrr authored Dec 13, 2024
1 parent 349efd2 commit 392894c
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 25 deletions.
9 changes: 4 additions & 5 deletions .projen/tasks.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion .projenrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { JsonPatch, cdk } from 'projen';
import { Stability } from 'projen/lib/cdk';
import { TrailingComma } from 'projen/lib/javascript';

const SCHEMA_VERSION: typeof import('./schema/version.json') = require('./schema/version.json');

export const project = new cdk.JsiiProject({
author: 'Amazon Web Services',
authorAddress: '',
Expand Down Expand Up @@ -55,7 +57,8 @@ export const project = new cdk.JsiiProject({
printWidth: 100,
},
},
nextVersionCommand: 'tsx ./projenrc/next-version.ts',
// This forces every release to be the major version from the data file
minMajorVersion: SCHEMA_VERSION.revision,
eslintOptions: {
prettier: true,
dirs: ['lib'],
Expand Down
4 changes: 2 additions & 2 deletions lib/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import INTEG_SCHEMA = require('../schema/integ.schema.json');
/**
* Version is shared for both manifests
*/
const SCHEMA_VERSION = require('../package.json').version;
import SCHEMA_VERSION = require('../schema/version.json');

/**
* Options for the loadManifest operation
Expand Down Expand Up @@ -138,7 +138,7 @@ export class Manifest {
* Fetch the current schema version number.
*/
public static version(): string {
return SCHEMA_VERSION;
return `${SCHEMA_VERSION.revision}.0.0`;
}

/**
Expand Down
16 changes: 0 additions & 16 deletions projenrc/next-version.ts

This file was deleted.

5 changes: 4 additions & 1 deletion projenrc/update.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { SCHEMAS } from './schema-definition';
import { generateSchema } from './update-schema';
import { maybeBumpVersion } from './versioning';

function update() {
const schemas: Record<string, any> = {};
for (const s of SCHEMAS) {
generateSchema(s);
schemas[s] = generateSchema(s);
}
maybeBumpVersion(schemas);
}

update();
44 changes: 44 additions & 0 deletions projenrc/versioning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as crypto from 'crypto';
import * as fs from 'fs';
import * as path from 'path';
import { SCHEMA_DIR } from './schema-definition';

export function maybeBumpVersion(schemas: Record<string, any>) {
const serializedSchema = JSON.stringify(sortJson(schemas), null, 2);

const versionFile = path.join(SCHEMA_DIR, 'version.json');
let current: SchemaVersionFile = JSON.parse(fs.readFileSync(versionFile, 'utf8'));
const schemaHash = sha256(serializedSchema);

if (current.schemaHash !== schemaHash) {
current = { schemaHash, revision: current.revision + 1 };
console.log(`Schemas changed, bumping version to ${current.revision}`);
}

fs.writeFileSync(versionFile, JSON.stringify(current, null, 2));
}

function sha256(x: string) {
const hash = crypto.createHash('sha256');
hash.update(x);
return hash.digest('hex');
}

interface SchemaVersionFile {
revision: number;
schemaHash: string;
}

function sortJson<A>(x: A): A {
if (Array.isArray(x)) {
return x;
}
if (typeof x === 'object' && x !== null) {
const ret: Record<string, any> = {};
for (const key of Object.keys(x).sort()) {
ret[key] = sortJson((x as any)[key]);
}
return ret as any;
}
return x;
}
4 changes: 4 additions & 0 deletions schema/version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"schemaHash": "f0ccc3212331af8a1c75830878d218fd667e5957063831be3b5bfd803b25f0cc",
"revision": 39
}

0 comments on commit 392894c

Please sign in to comment.