dsh 0.2.0-rc.2: in-container update (experimental channel), path-agnostic compose, upstream patches adapted to 0.1.x/0.2.x
This commit is contained in:
commit
e6dcef9bf5
302 files changed
+75178
No files matched your search
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { createHash, createPrivateKey, createPublicKey, sign } from 'node:crypto'
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||
import { basename, join, resolve } from 'node:path'
|
||||
import { canonicalJson } from '../lib/canonical-json.mjs'
|
||||
import { parseStable } from '../lib/contracts.mjs'
|
||||
|
||||
const [configArg, privateKeyArg, outputArg] = process.argv.slice(2)
|
||||
if (configArg === undefined || privateKeyArg === undefined || outputArg === undefined) {
|
||||
console.error('usage: build-release.mjs <release-config.json> <current-release-private.pem> <output-dir>')
|
||||
process.exit(64)
|
||||
}
|
||||
const config = JSON.parse(await readFile(resolve(configArg), 'utf8'))
|
||||
const privateKey = createPrivateKey(await readFile(resolve(privateKeyArg)))
|
||||
if (privateKey.asymmetricKeyType !== 'ed25519') throw new Error('Release private key must be Ed25519')
|
||||
const publicDer = createPublicKey(privateKey).export({ format: 'der', type: 'spki' })
|
||||
const keyId = createHash('sha256').update(publicDer).digest('hex')
|
||||
if (keyId !== config.currentKeyId) throw new Error('Release private key is not the configured current key')
|
||||
const artifacts = []
|
||||
for (const artifact of config.artifacts) {
|
||||
const bytes = await readFile(resolve(artifact.path))
|
||||
artifacts.push({
|
||||
id: artifact.id,
|
||||
mediaType: artifact.mediaType,
|
||||
sha256: createHash('sha256').update(bytes).digest('hex'),
|
||||
size: bytes.byteLength,
|
||||
url: new URL(basename(artifact.path), config.artifactBaseUrl).href,
|
||||
})
|
||||
}
|
||||
let issuedAt
|
||||
if (process.env.SOURCE_DATE_EPOCH === undefined) issuedAt = new Date().toISOString()
|
||||
else {
|
||||
const sourceDateEpoch = Number(process.env.SOURCE_DATE_EPOCH)
|
||||
if (!Number.isSafeInteger(sourceDateEpoch) || sourceDateEpoch < 0) throw new Error('SOURCE_DATE_EPOCH must be a non-negative safe integer')
|
||||
issuedAt = new Date(sourceDateEpoch * 1000).toISOString()
|
||||
}
|
||||
const stable = canonicalJson({
|
||||
schema: 1,
|
||||
updateApi: 1,
|
||||
keyringGeneration: config.keyringGeneration,
|
||||
targetSequence: config.targetSequence,
|
||||
issuedAt,
|
||||
artifacts,
|
||||
desired: config.desired,
|
||||
officialDshPolicy: config.officialDshPolicy,
|
||||
})
|
||||
parseStable(stable)
|
||||
const signature = canonicalJson({
|
||||
schema: 1,
|
||||
algorithm: 'Ed25519',
|
||||
keyId,
|
||||
signature: sign(null, stable, privateKey).toString('base64'),
|
||||
})
|
||||
const output = resolve(outputArg)
|
||||
await mkdir(output, { recursive: true })
|
||||
await writeFile(join(output, 'stable.json'), stable, { flag: 'wx' })
|
||||
await writeFile(join(output, 'stable.sig.json'), signature, { flag: 'wx' })
|
||||
Reference in new issue
Block a user