TechDocs: Add etag to techdocs_metadata.json

This commit is contained in:
Himanshu Mishra
2021-02-15 19:38:07 +01:00
parent 29fbdc7e9a
commit b16b096f58
5 changed files with 73 additions and 5 deletions
@@ -29,6 +29,7 @@ import {
isValidRepoUrlForMkdocs,
patchMkdocsYmlPreBuild,
runDockerContainer,
storeEtagMetadata,
} from './helpers';
const mockEntity = {
@@ -362,7 +363,7 @@ describe('helpers', () => {
await expect(
addBuildTimestampMetadata(filePath, mockLogger),
).rejects.toThrowError();
).rejects.toThrowError('Unexpected token d in JSON at position 0');
});
it('should add build timestamp to the metadata json', async () => {
@@ -374,4 +375,37 @@ describe('helpers', () => {
expect(json.build_timestamp).toBeLessThanOrEqual(Date.now());
});
});
describe('storeEtagMetadata', () => {
beforeEach(() => {
mockFs.restore();
mockFs({
[rootDir]: {
'invalid_techdocs_metadata.json': 'dsds',
'techdocs_metadata.json': '{"site_name": "Tech Docs"}',
},
});
});
afterEach(() => {
mockFs.restore();
});
it('should throw error when the JSON is invalid', async () => {
const filePath = path.join(rootDir, 'invalid_techdocs_metadata.json');
await expect(
storeEtagMetadata(filePath, 'etag123abc'),
).rejects.toThrowError('Unexpected token d in JSON at position 0');
});
it('should add etag to the metadata json', async () => {
const filePath = path.join(rootDir, 'techdocs_metadata.json');
await storeEtagMetadata(filePath, 'etag123abc');
const json = await fs.readJson(filePath);
expect(json.etag).toBe('etag123abc');
});
});
});
@@ -306,3 +306,20 @@ export const addBuildTimestampMetadata = async (
await fs.writeJson(techdocsMetadataPath, json);
return;
};
/**
* Update the techdocs_metadata.json to add etag of the prepared tree (e.g. commit SHA or actual Etag of the resource).
* This is helpful to check if a TechDocs site in storage has gone outdated, without maintaining an in-memory build info
* per Backstage instance.
*
* @param {string} techdocsMetadataPath File path to techdocs_metadata.json
* @param {string} etag
*/
export const storeEtagMetadata = async (
techdocsMetadataPath: string,
etag: string,
): Promise<void> => {
const json = await fs.readJson(techdocsMetadataPath);
json.etag = etag;
await fs.writeJson(techdocsMetadataPath, json);
};
@@ -23,6 +23,7 @@ import {
patchMkdocsYmlPreBuild,
runCommand,
runDockerContainer,
storeEtagMetadata,
} from './helpers';
import { GeneratorBase, GeneratorRunOptions } from './types';
@@ -62,6 +63,7 @@ export class TechdocsGenerator implements GeneratorBase {
outputDir,
dockerClient,
parsedLocationAnnotation,
etag,
}: GeneratorRunOptions): Promise<void> {
const [log, logStream] = createStream();
@@ -119,12 +121,24 @@ export class TechdocsGenerator implements GeneratorBase {
);
}
// Post Generate steps
/**
* Post Generate steps
*/
// Add build timestamp to techdocs_metadata.json
addBuildTimestampMetadata(
// Creates techdocs_metadata.json if file does not exist.
await addBuildTimestampMetadata(
path.join(outputDir, 'techdocs_metadata.json'),
this.logger,
);
// Add etag of the prepared tree to techdocs_metadata.json
// Assumes that the file already exists.
if (etag) {
await storeEtagMetadata(
path.join(outputDir, 'techdocs_metadata.json'),
etag,
);
}
}
}
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Writable } from 'stream';
import Docker from 'dockerode';
import { Entity } from '@backstage/catalog-model';
import Docker from 'dockerode';
import { Writable } from 'stream';
import { ParsedLocationAnnotation } from '../../helpers';
/**
@@ -25,6 +25,7 @@ import { ParsedLocationAnnotation } from '../../helpers';
* @param {string} outputDir Directory to store generated docs in. Usually - a newly created temporary directory.
* @param {Docker} dockerClient A docker client to run any generator on top of your directory
* @param {ParsedLocationAnnotation} parsedLocationAnnotation backstage.io/techdocs-ref annotation of an entity
* @param {string} etag A unique identifier for the prepared tree e.g. commit SHA. If provided it will be stored in techdocs_metadata.json.
* @param {Writable} [logStream] A dedicated log stream
*/
export type GeneratorRunOptions = {
@@ -32,6 +33,7 @@ export type GeneratorRunOptions = {
outputDir: string;
dockerClient: Docker;
parsedLocationAnnotation?: ParsedLocationAnnotation;
etag?: string;
logStream?: Writable;
};
@@ -130,6 +130,7 @@ export class DocsBuilder {
outputDir,
dockerClient: this.dockerClient,
parsedLocationAnnotation,
etag,
});
this.logger.debug(`Generated files temporarily stored at ${outputDir}`);