mirror of
https://github.com/getumbrel/umbrel.git
synced 2024-11-20 17:18:37 +03:00
Cleanup CI
Adds new npm scripts: - `prepare-release` to prepare release assets - `timestamp-release` to generate OTS proof - `generate-release-notes` to automatically generate markdown release notes for a given range between two tags Updates CI to use the npm scripts internally.
This commit is contained in:
parent
090c5b8e04
commit
cb20f682e4
44
.github/workflows/ci.yml
vendored
44
.github/workflows/ci.yml
vendored
@ -12,19 +12,37 @@ jobs:
|
||||
run:
|
||||
working-directory: ./server
|
||||
steps:
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
- run: docker buildx create --use
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
# TODO Clean this up into a release script
|
||||
- run: cd build && mv umbreld-amd64 umbreld && tar -czvf umbreld-${{ github.ref_name }}-amd64.tar.gz umbreld && rm umbreld
|
||||
- run: cd build && mv umbreld-arm64 umbreld && tar -czvf umbreld-${{ github.ref_name }}-arm64.tar.gz umbreld && rm umbreld
|
||||
- run: cd ../ && git archive --format=tar.gz --output server/build/umbrel-${{ github.ref_name }}.tar.gz --prefix=umbrel-${{ github.ref_name }}/ ${{ github.ref_name }}
|
||||
- run: sha256sum build/* > build/SHA256SUMS
|
||||
- run: npx opentimestamps stamp build/SHA256SUMS || true # Don't fail the release if timestamping fails
|
||||
# TODO Generate release notes
|
||||
- uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
|
||||
with:
|
||||
# We need this to get all commit history and tags to generate release notes
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Docker buildx
|
||||
run: docker buildx create --use
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build release
|
||||
run: npm run build
|
||||
|
||||
- name: Prepare release assets
|
||||
run: npm run prepare-release -- ${{ github.ref_name }}
|
||||
|
||||
- name: Timestamp release
|
||||
continue-on-error: true
|
||||
run: npm run timestamp-release
|
||||
|
||||
- name: Generate release notes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: npm run generate-release-notes
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
|
||||
with:
|
||||
draft: true
|
||||
name: umbrelOS ${{ github.ref_name }}
|
||||
files: server/build/*
|
||||
files: server/release/*
|
||||
body_path: server/release-notes.md
|
8
package-lock.json
generated
8
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "umbrel",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
"name": "umbrel",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
||||
|
@ -6,4 +6,4 @@
|
||||
"dev:restart": "npm run dev:stop && npm run dev:start",
|
||||
"dev:shell": "multipass shell umbrel-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ else
|
||||
fi
|
||||
echo "Detected architecture: ${binary_arch}"
|
||||
|
||||
binary_source_location="${UPDATE_ROOT}/server/build/umbreld-${binary_arch}"
|
||||
binary_source_location="${UPDATE_ROOT}/server/build/linux_${binary_arch}/umbreld"
|
||||
binary_destination_location="${UMBREL_ROOT}/bin/umbreld"
|
||||
|
||||
# Download umbreld release binary if we don't have a local dev build
|
||||
|
2
server/.gitignore
vendored
2
server/.gitignore
vendored
@ -1,2 +1,4 @@
|
||||
node_modules
|
||||
build
|
||||
release
|
||||
release-notes.md
|
||||
|
@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
import path from 'node:path'
|
||||
import os from 'node:os'
|
||||
|
||||
import caxa from 'caxa'
|
||||
import fse from 'fs-extra'
|
||||
@ -11,28 +10,19 @@ const $$ = $({stdio: 'inherit'})
|
||||
const BUILD_DIRECTORY = 'build'
|
||||
|
||||
async function runMultiArchDockerBuilds(architectures) {
|
||||
let buildDirectory = BUILD_DIRECTORY
|
||||
if (architectures.length === 1) buildDirectory += `/linux_${architectures[0]}`
|
||||
const platforms = architectures.map(architecture => `linux/${architecture}`).join(',')
|
||||
await $$`docker buildx build --platform ${platforms} --output ${BUILD_DIRECTORY} .`
|
||||
// Clean up Docker's platform-specific build directories
|
||||
for (const buildSubDirectory of await fse.readdir(BUILD_DIRECTORY)) {
|
||||
const platformBuildPath = `${BUILD_DIRECTORY}/${buildSubDirectory}`
|
||||
const isPlatformBuild = buildSubDirectory.startsWith('linux_') && (await fse.stat(platformBuildPath)).isDirectory()
|
||||
if (!isPlatformBuild) continue
|
||||
for (const file of await fse.readdir(platformBuildPath)) {
|
||||
await fse.move(`${platformBuildPath}/${file}`, `${BUILD_DIRECTORY}/${file}`, { overwrite: true })
|
||||
}
|
||||
await fse.remove(platformBuildPath)
|
||||
}
|
||||
await $$`docker buildx build --platform ${platforms} --output ${buildDirectory} .`
|
||||
}
|
||||
|
||||
async function buildBinary() {
|
||||
const {bin} = await fse.readJson('package.json')
|
||||
const entrypoint = path.join('{{caxa}}', bin)
|
||||
const architecture = os.arch() === 'x64' ? 'amd64' : os.arch()
|
||||
await caxa({
|
||||
input: '.',
|
||||
exclude: [BUILD_DIRECTORY],
|
||||
output: `${BUILD_DIRECTORY}/umbreld-${architecture}`,
|
||||
output: `${BUILD_DIRECTORY}/umbreld`,
|
||||
command: [
|
||||
"{{caxa}}/node_modules/.bin/node",
|
||||
entrypoint,
|
||||
|
87
server/generate-release-notes.js
Executable file
87
server/generate-release-notes.js
Executable file
@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env node
|
||||
import {$} from 'execa'
|
||||
import fse from 'fs-extra'
|
||||
import got from 'got'
|
||||
|
||||
const githubUsernames = {
|
||||
'Luke Childs <lukechilds123@gmail.com>': '@lukechilds',
|
||||
'Nathan Fretz <nmfretz@gmail.com>': '@nmfretz',
|
||||
'Mayank Chhabra <mayankchhabra9@gmail.com>': '@mayankchhabra',
|
||||
}
|
||||
|
||||
async function lookupUsername(author) {
|
||||
// If the username starts with @ we probably already have a GitHub username
|
||||
if (author.startsWith('@')) return author.split(' ')[0]
|
||||
|
||||
// If we already havfe the username cached, return it
|
||||
if (githubUsernames[author]) return githubUsernames[author]
|
||||
|
||||
// Attempt to lookup the GitHub username from the commit details
|
||||
try {
|
||||
console.log(`Looking up ${author}`)
|
||||
const data = await got(`https://api.github.com/search/users?q=${author}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.GITHUB_TOKEN}`
|
||||
},
|
||||
}).json()
|
||||
const username = data?.items?.[0]?.login
|
||||
|
||||
if (username) {
|
||||
// Cache for next time
|
||||
githubUsernames[author] = `@${username}`
|
||||
return githubUsernames[author]
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error.message)
|
||||
// If anything goes wrong just fall back to commit credentials
|
||||
}
|
||||
|
||||
// If we didn't find anything, cache the original commit details to save additional failing lookups
|
||||
// Also log the failure to help us find it so we can manually update
|
||||
githubUsernames[author] = author
|
||||
console.log('Failed')
|
||||
|
||||
// Return the original commit details if we didn't find anything
|
||||
return author
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let range = process.argv[2]
|
||||
|
||||
if (!range) {
|
||||
const gitTag = await $`git tag --sort=-creatordate`
|
||||
const tags = gitTag.stdout.split('\n')
|
||||
range = `${tags[1]}...${tags[0]}`
|
||||
}
|
||||
|
||||
const markdown = []
|
||||
markdown.push('## Changes')
|
||||
markdown.push('')
|
||||
markdown.push(`https://github.com/getumbrel/umbrel/compare/${range}`)
|
||||
markdown.push('')
|
||||
|
||||
const format = '===COMMIT_DELIMITER===%n%h%n%s%n%an <%ae>%n%b'
|
||||
const log = await $`git log --pretty=format:${format} ${range}`
|
||||
const commits = log.stdout.split('===COMMIT_DELIMITER===\n')
|
||||
for (const commit of commits) {
|
||||
const [hash, title, author, ...body] = commit.split('\n')
|
||||
if (!hash) continue
|
||||
|
||||
const coAuthors = body
|
||||
.filter(line => line.startsWith('Co-authored-by:'))
|
||||
.map(line => line.replace('Co-authored-by: ', '').trim())
|
||||
const authors = []
|
||||
for (const person of [author, ...coAuthors]) {
|
||||
authors.push(await lookupUsername(person))
|
||||
}
|
||||
|
||||
markdown.push(`- ${title} (${hash}) ${authors.join(' ')}`)
|
||||
}
|
||||
|
||||
console.log('')
|
||||
console.log(markdown.join('\n'))
|
||||
await fse.writeFile('release-notes.md', markdown.join('\n'))
|
||||
|
||||
}
|
||||
|
||||
await main()
|
213
server/package-lock.json
generated
213
server/package-lock.json
generated
@ -26,6 +26,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"caxa": "^3.0.1",
|
||||
"got": "^13.0.0",
|
||||
"opentimestamps": "^0.4.9"
|
||||
}
|
||||
},
|
||||
@ -61,6 +62,36 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.4.1.tgz",
|
||||
"integrity": "sha512-axlrvsHlHlFmKKMEg4VyvMzFr93JWJj4eIfXY1STVuO2fsImCa7ncaiG5gC8HKOX590AW5RtRsC41/B+OfrSqw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@szmarczak/http-timer": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
|
||||
"integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"defer-to-connect": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/http-cache-semantics": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
|
||||
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/jsonwebtoken": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
|
||||
@ -473,6 +504,45 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-lookup": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz",
|
||||
"integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-request": {
|
||||
"version": "10.2.12",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.12.tgz",
|
||||
"integrity": "sha512-qtWGB5kn2OLjx47pYUkWicyOpK1vy9XZhq8yRTXOy+KAmjjESSRLx6SiExnnaGGUP1NM6/vmygMu0fGylNh9tw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/http-cache-semantics": "^4.0.1",
|
||||
"get-stream": "^6.0.1",
|
||||
"http-cache-semantics": "^4.1.1",
|
||||
"keyv": "^4.5.2",
|
||||
"mimic-response": "^4.0.0",
|
||||
"normalize-url": "^8.0.0",
|
||||
"responselike": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-request/node_modules/mimic-response": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
|
||||
"integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||
@ -767,6 +837,15 @@
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/defer-to-connect": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@ -1131,6 +1210,15 @@
|
||||
"node": ">= 0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data-encoder": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
|
||||
"integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||
@ -1270,6 +1358,31 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/got": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz",
|
||||
"integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": "^5.2.0",
|
||||
"@szmarczak/http-timer": "^5.0.1",
|
||||
"cacheable-lookup": "^7.0.0",
|
||||
"cacheable-request": "^10.2.8",
|
||||
"decompress-response": "^6.0.0",
|
||||
"form-data-encoder": "^2.1.2",
|
||||
"get-stream": "^6.0.1",
|
||||
"http2-wrapper": "^2.1.10",
|
||||
"lowercase-keys": "^3.0.0",
|
||||
"p-cancelable": "^3.0.0",
|
||||
"responselike": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/got?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
@ -1352,6 +1465,12 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/http-cache-semantics": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
|
||||
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
@ -1382,6 +1501,19 @@
|
||||
"npm": ">=1.3.7"
|
||||
}
|
||||
},
|
||||
"node_modules/http2-wrapper": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz",
|
||||
"integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"quick-lru": "^5.1.1",
|
||||
"resolve-alpn": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
|
||||
@ -1540,6 +1672,12 @@
|
||||
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-schema": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
||||
@ -1623,6 +1761,15 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz",
|
||||
"integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lazystream": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz",
|
||||
@ -1700,6 +1847,18 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/lowercase-keys": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
|
||||
"integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
@ -1910,6 +2069,18 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-url": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz",
|
||||
"integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
|
||||
@ -2021,6 +2192,15 @@
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/p-cancelable": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz",
|
||||
"integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
}
|
||||
},
|
||||
"node_modules/p-retry": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-5.1.2.tgz",
|
||||
@ -2209,6 +2389,18 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/quick-lru": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
@ -2393,6 +2585,27 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-alpn": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
|
||||
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/responselike": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz",
|
||||
"integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lowercase-keys": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/retry": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
|
||||
|
@ -6,6 +6,9 @@
|
||||
"bin": "./index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"prepare-release": "node prepare-release.js",
|
||||
"timestamp-release": "ots-cli.js stamp release/SHA256SUMS",
|
||||
"generate-release-notes": "node generate-release-notes.js",
|
||||
"build": "node build.js"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -24,6 +27,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"caxa": "^3.0.1",
|
||||
"got": "^13.0.0",
|
||||
"opentimestamps": "^0.4.9"
|
||||
}
|
||||
}
|
||||
|
31
server/prepare-release.js
Executable file
31
server/prepare-release.js
Executable file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env node
|
||||
import fse from 'fs-extra'
|
||||
import {$} from 'execa'
|
||||
|
||||
const BUILD_DIRECTORY = 'build'
|
||||
const RELEASE_DIRECTORY = 'release'
|
||||
|
||||
async function main() {
|
||||
const release = process.argv[2]
|
||||
|
||||
if (!release) throw new Error('Release argument is required.')
|
||||
|
||||
console.log('Cleaning release directory...')
|
||||
await fse.remove(RELEASE_DIRECTORY)
|
||||
await fse.ensureDir(RELEASE_DIRECTORY)
|
||||
|
||||
console.log('Preparing release assets...')
|
||||
await Promise.all([
|
||||
$`tar -czvf ${RELEASE_DIRECTORY}/umbreld-${release}-amd64.tar.gz -C ${BUILD_DIRECTORY}/linux_amd64 umbreld`,
|
||||
$`tar -czvf ${RELEASE_DIRECTORY}/umbreld-${release}-arm64.tar.gz -C ${BUILD_DIRECTORY}/linux_arm64 umbreld`,
|
||||
$`git archive --format=tar.gz --output ${RELEASE_DIRECTORY}/umbrel-${release}.tar.gz --prefix=umbrel-${release}/ HEAD`,
|
||||
])
|
||||
|
||||
console.log('Generating checksums...')
|
||||
const releaseAssets = await fse.readdir(RELEASE_DIRECTORY)
|
||||
const checksums = await $({cwd: RELEASE_DIRECTORY})`sha256sum ${releaseAssets}`
|
||||
console.log(checksums.stdout)
|
||||
await fse.writeFile(`${RELEASE_DIRECTORY}/SHA256SUMS`, checksums.stdout)
|
||||
}
|
||||
|
||||
await main()
|
Loading…
Reference in New Issue
Block a user