blob: 2992121f013621242a0e67b948dff550e46e8c16 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Records where public/api/fineract.json came from.
*
* Nothing used to. "Which Fineract is this client for?" could only be answered
* from an `info.version` of `1.16.0-SNAPSHOT`, which is the same string for
* months at a time and says nothing about which build produced it.
*
* Two hashes are stored deliberately:
* upstreamSha256 — the raw bytes as upstream serves them (minified). This is
* the sync workflow's short-circuit key: exact and cheap.
* committedSha256 — the file as committed, which Prettier has reformatted. Lets
* a human check the spec was not hand-edited.
*
* Everything comes from the environment so the workflow never interpolates
* ${{ }} into a script body.
*
* node scripts/write-provenance.mjs <spec.json> <upstream-raw.json>
*/
import { readFileSync, writeFileSync } from 'node:fs';
import { createHash } from 'node:crypto';
const [committedPath, upstreamRawPath] = process.argv.slice(2);
const OUTPUT = 'public/api/fineract.provenance.json';
const sha256 = (buffer) => createHash('sha256').update(buffer).digest('hex');
const committedRaw = readFileSync(committedPath);
const upstreamRaw = upstreamRawPath ? readFileSync(upstreamRawPath) : committedRaw;
const spec = JSON.parse(committedRaw.toString('utf8'));
const operationCount = Object.values(spec.paths ?? {}).reduce(
(total, item) =>
total +
Object.keys(item ?? {}).filter((key) =>
['get', 'put', 'post', 'delete', 'patch', 'head', 'options'].includes(key),
).length,
0,
);
const provenance = {
$comment:
'Provenance for public/api/fineract.json. Written by .github/workflows/api-spec-sync.yml; do not edit by hand.',
license: 'Apache-2.0',
schemaVersion: 1,
fetchedAt: process.env.FETCHED_AT ?? new Date().toISOString(),
source: {
project: 'apache/fineract',
method: process.env.FETCH_METHOD ?? 'http',
url: process.env.FETCH_URL ?? '',
image: {
requested: process.env.IMAGE_REQUESTED ?? 'apache/fineract:latest',
ref: process.env.IMAGE_REF ?? '',
digest: process.env.IMAGE_DIGEST ?? '',
},
// Docker Hub tags apache/fineract images with the upstream commit SHA, so this
// is a real commit rather than a guess — when the reverse lookup succeeds.
commit: process.env.UPSTREAM_COMMIT || 'unknown',
},
spec: {
path: 'public/api/fineract.json',
infoVersion: spec.info?.version ?? 'unknown',
upstreamSha256: sha256(upstreamRaw),
committedSha256: sha256(committedRaw),
committedBytes: committedRaw.length,
pathCount: Object.keys(spec.paths ?? {}).length,
operationCount,
schemaCount: Object.keys(spec.components?.schemas ?? {}).length,
},
generator: {
tool: 'openapi-generator-cli',
version: JSON.parse(readFileSync('openapitools.json', 'utf8'))['generator-cli'].version,
generatorName: 'typescript-angular',
preprocessor: 'scripts/preprocess-spec.mjs',
output: 'src/app/api',
},
workflow: {
runUrl: process.env.RUN_URL ?? '',
},
};
writeFileSync(OUTPUT, `${JSON.stringify(provenance, null, 2)}\n`);
console.log(`Wrote ${OUTPUT} (info.version ${provenance.spec.infoVersion})`);