Smarter release workflow (#1525)

* js-based publish workflow

* don't create release if not using tag

* rename

* update lockfile

* remove unnecessary tsconfigs

* replace old publish action

* dumb

* esmodule moment

* glob files

* lockfile

* build app bundle

* Fix artifact upload hopefully

* upload artifacts from root

* skill issue ffs

* Use copy instead of move

* hopefully last one

* artifcats

* make .artifacts -_-

* ffs

* Make cp recursive, so it work with dirs

* build

* separate updater & standalone targets

* create draft release

---------

Co-authored-by: Vítor Vasconcellos <vasconcellos.dev@gmail.com>
This commit is contained in:
Brendan Allan 2023-10-13 16:56:54 +08:00 committed by GitHub
parent 39744b5c55
commit b27c5ac49f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 364 additions and 59 deletions

View file

@ -0,0 +1 @@
!dist

View file

@ -5,58 +5,10 @@ inputs:
description: target triples for built artifact
profile:
description: "'debug' or 'release'"
os:
description: "'darwin', 'windows', or 'linux'"
arch:
description: "'x86_64' or 'aarch64'"
runs:
using: 'composite'
steps:
- name: Determine short GitHub SHA
shell: bash
run: |
export GITHUB_SHA_SHORT=$(git rev-parse --short "$GITHUB_SHA")
echo "GITHUB_SHA_SHORT=$GITHUB_SHA_SHORT" >> $GITHUB_ENV
- name: Publish artifacts (Linux - AppImage)
if: ${{ matrix.settings.host == 'ubuntu-20.04' }}
uses: actions/upload-artifact@v3
with:
name: Spacedrive-AppImage-${{ inputs.target }}-${{ env.GITHUB_SHA_SHORT }}
path: target/${{ inputs.target }}/${{ inputs.profile }}/bundle/appimage/*.AppImage
if-no-files-found: error
retention-days: 1
- name: Publish artifacts (Debian - deb)
if: ${{ matrix.settings.host == 'ubuntu-20.04' }}
uses: actions/upload-artifact@v3
with:
name: Spacedrive-deb-${{ inputs.target }}-${{ env.GITHUB_SHA_SHORT }}
path: target/${{ inputs.target }}/${{ inputs.profile }}/bundle/deb/*.deb
if-no-files-found: error
retention-days: 1
- name: Publish artifacts (Windows - msi)
if: ${{ matrix.settings.host == 'windows-latest' }}
uses: actions/upload-artifact@v3
with:
name: Spacedrive-Windows-msi-${{ inputs.target }}-${{ env.GITHUB_SHA_SHORT }}
path: target/${{ inputs.target }}/${{ inputs.profile }}/bundle/msi/*.msi
if-no-files-found: error
retention-days: 1
- name: Publish artifacts (macOS - dmg)
if: ${{ matrix.settings.host == 'macos-latest' }}
uses: actions/upload-artifact@v3
with:
name: Spacedrive-macOS-dmg-${{ inputs.target }}-${{ env.GITHUB_SHA_SHORT }}
path: target/${{ inputs.target }}/${{ inputs.profile }}/bundle/dmg/*.dmg
if-no-files-found: error
retention-days: 1
- name: Publish updater binaries
uses: actions/upload-artifact@v3
with:
name: Spacedrive-Updater-${{ inputs.target }}-${{ env.GITHUB_SHA_SHORT }}
path: |
target/${{ inputs.target }}/${{ inputs.profile }}/bundle/**/*.tar.gz*
target/${{ inputs.target }}/${{ inputs.profile }}/bundle/**/*.zip*
!target/**/deb/**/*.tar.gz
if-no-files-found: error
retention-days: 1
using: node20
main: dist/index.js

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,102 @@
import * as artifact from '@actions/artifact';
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import * as io from '@actions/io';
type OS = 'darwin' | 'windows' | 'linux';
type Arch = 'x64' | 'arm64';
type TargetConfig = { bundle: string; ext: string };
type BuildTarget = {
updater: TargetConfig;
standalone: Array<TargetConfig>;
};
const OS_TARGETS = {
darwin: {
updater: {
bundle: 'macos',
ext: 'app.tar.gz'
},
standalone: [{ ext: 'dmg', bundle: 'dmg' }]
},
windows: {
updater: {
bundle: 'msi',
ext: 'msi.zip'
},
standalone: [{ ext: 'msi', bundle: 'msi' }]
},
linux: {
updater: {
bundle: 'appimage',
ext: 'AppImage.tar.gz'
},
standalone: [
{ ext: 'deb', bundle: 'deb' },
{ ext: 'AppImage', bundle: 'appimage' }
]
}
} satisfies Record<OS, BuildTarget>;
// Workflow inputs
const OS: OS = core.getInput('os') as any;
const ARCH: Arch = core.getInput('arch') as any;
const TARGET = core.getInput('target');
const PROFILE = core.getInput('profile');
const BUNDLE_DIR = `target/${TARGET}/${PROFILE}/bundle`;
const ARTIFACTS_DIR = '.artifacts';
const ARTIFACT_BASE = `Spacedrive-${OS}-${ARCH}`;
const UPDATER_ARTIFACT_NAME = `Spacedrive-Updater-${OS}-${ARCH}`;
const client = artifact.create();
async function globFiles(pattern: string) {
const globber = await glob.create(pattern);
return await globber.glob();
}
async function uploadUpdater({ bundle, ext }: TargetConfig) {
const files = await globFiles(`${BUNDLE_DIR}/${bundle}/*.${ext}*`);
const updaterPath = files.find((file) => file.endsWith(ext));
if (!updaterPath) return console.error(`Updater path not found. Files: ${files}`);
const artifactPath = `${ARTIFACTS_DIR}/${UPDATER_ARTIFACT_NAME}.${ext}`;
// https://tauri.app/v1/guides/distribution/updater#update-artifacts
await io.cp(updaterPath, artifactPath);
await io.cp(`${updaterPath}.sig`, `${artifactPath}.sig`);
await client.uploadArtifact(
UPDATER_ARTIFACT_NAME,
[artifactPath, `${artifactPath}.sig`],
ARTIFACTS_DIR
);
}
async function uploadStandalone({ bundle, ext }: TargetConfig) {
const files = await globFiles(`${BUNDLE_DIR}/${bundle}/*.${ext}*`);
const standalonePath = files.find((file) => file.endsWith(ext));
if (!standalonePath) return console.error(`Standalone path not found. Files: ${files}`);
const artifactName = `${ARTIFACT_BASE}.${ext}`;
const artifactPath = `${ARTIFACTS_DIR}/${artifactName}`;
await io.cp(standalonePath, artifactPath, { recursive: true });
await client.uploadArtifact(artifactName, [artifactPath], ARTIFACTS_DIR);
}
async function run() {
await io.mkdirP(ARTIFACTS_DIR);
const { updater, standalone } = OS_TARGETS[OS];
await uploadUpdater(updater);
for (const config of standalone) {
await uploadStandalone(config);
}
}
run();

View file

@ -0,0 +1,16 @@
{
"private": true,
"scripts": {
"build": "ncc build index.ts --minify"
},
"dependencies": {
"@actions/artifact": "^1.1.2",
"@actions/core": "^1.10.1",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.4.0",
"@actions/io": "^1.1.3"
},
"devDependencies": {
"@vercel/ncc": "^0.38.0"
}
}

View file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "es2015" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"module": "esnext" /* Specify what module code is generated. */,
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"strict": true /* Enable all strict type-checking options. */,
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}

View file

@ -2,29 +2,35 @@ name: Release
on:
workflow_dispatch:
# NOTE: For Linux builds, we can only build with Ubuntu. It should be the oldest base system we intend to support. See PR-759 & https://tauri.app/v1/guides/building/linux for reference.
jobs:
desktop-main:
strategy:
fail-fast: true
matrix:
settings:
- host: macos-latest
target: x86_64-apple-darwin
bundles: dmg
bundles: app,dmg
os: darwin
arch: x86_64
- host: macos-latest
target: aarch64-apple-darwin
bundles: dmg
bundles: app,dmg
os: darwin
arch: aarch64
- host: windows-latest
target: x86_64-pc-windows-msvc
bundles: msi
os: windows
arch: x86_64
# - host: windows-latest
# target: aarch64-pc-windows-msvc
- host: ubuntu-20.04
target: x86_64-unknown-linux-gnu
bundles: appimage,deb
bundles: deb,appimage
os: linux
arch: x86_64
# - host: ubuntu-20.04
# target: x86_64-unknown-linux-musl
# - host: ubuntu-20.04
@ -112,5 +118,24 @@ jobs:
- name: Publish Artifacts
uses: ./.github/actions/publish-artifacts
with:
os: ${{ matrix.settings.os }}
arch: ${{ matrix.settings.arch }}
target: ${{ matrix.settings.target }}
profile: release
release:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
name: Create Release
needs: desktop-main
permissions:
contents: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v3
- name: Create Release
uses: softprops/action-gh-release@v1
with:
draft: true
files: "*/**"

View file

@ -48,6 +48,28 @@ importers:
specifier: ^4.4
version: 4.4.10(@types/node@18.17.12)
.github/actions/publish-artifacts:
dependencies:
'@actions/artifact':
specifier: ^1.1.2
version: 1.1.2
'@actions/core':
specifier: ^1.10.1
version: 1.10.1
'@actions/github':
specifier: ^6.0.0
version: 6.0.0
'@actions/glob':
specifier: ^0.4.0
version: 0.4.0
'@actions/io':
specifier: ^1.1.3
version: 1.1.3
devDependencies:
'@vercel/ncc':
specifier: ^0.38.0
version: 0.38.0
apps/desktop:
dependencies:
'@rspc/client':
@ -1116,6 +1138,49 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/@actions/artifact@1.1.2:
resolution: {integrity: sha512-1gLONA4xw3/Q/9vGxKwkFdV9u1LE2RWGx/IpAqg28ZjprCnJFjwn4pA7LtShqg5mg5WhMek2fjpyH1leCmOlQQ==}
dependencies:
'@actions/core': 1.10.1
'@actions/http-client': 2.2.0
tmp: 0.2.1
tmp-promise: 3.0.3
dev: false
/@actions/core@1.10.1:
resolution: {integrity: sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==}
dependencies:
'@actions/http-client': 2.2.0
uuid: 8.3.2
dev: false
/@actions/github@6.0.0:
resolution: {integrity: sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==}
dependencies:
'@actions/http-client': 2.2.0
'@octokit/core': 5.0.1
'@octokit/plugin-paginate-rest': 9.0.0(@octokit/core@5.0.1)
'@octokit/plugin-rest-endpoint-methods': 10.0.1(@octokit/core@5.0.1)
dev: false
/@actions/glob@0.4.0:
resolution: {integrity: sha512-+eKIGFhsFa4EBwaf/GMyzCdWrXWymGXfFmZU3FHQvYS8mPcHtTtZONbkcqqUMzw9mJ/pImEBFET1JNifhqGsAQ==}
dependencies:
'@actions/core': 1.10.1
minimatch: 3.1.2
dev: false
/@actions/http-client@2.2.0:
resolution: {integrity: sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==}
dependencies:
tunnel: 0.0.6
undici: 5.25.4
dev: false
/@actions/io@1.1.3:
resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==}
dev: false
/@alloc/quick-lru@5.2.0:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
@ -7442,6 +7507,92 @@ packages:
rimraf: 3.0.2
dev: false
/@octokit/auth-token@4.0.0:
resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==}
engines: {node: '>= 18'}
dev: false
/@octokit/core@5.0.1:
resolution: {integrity: sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==}
engines: {node: '>= 18'}
dependencies:
'@octokit/auth-token': 4.0.0
'@octokit/graphql': 7.0.2
'@octokit/request': 8.1.4
'@octokit/request-error': 5.0.1
'@octokit/types': 12.0.0
before-after-hook: 2.2.3
universal-user-agent: 6.0.0
dev: false
/@octokit/endpoint@9.0.1:
resolution: {integrity: sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==}
engines: {node: '>= 18'}
dependencies:
'@octokit/types': 12.0.0
is-plain-object: 5.0.0
universal-user-agent: 6.0.0
dev: false
/@octokit/graphql@7.0.2:
resolution: {integrity: sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==}
engines: {node: '>= 18'}
dependencies:
'@octokit/request': 8.1.4
'@octokit/types': 12.0.0
universal-user-agent: 6.0.0
dev: false
/@octokit/openapi-types@19.0.0:
resolution: {integrity: sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==}
dev: false
/@octokit/plugin-paginate-rest@9.0.0(@octokit/core@5.0.1):
resolution: {integrity: sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=5'
dependencies:
'@octokit/core': 5.0.1
'@octokit/types': 12.0.0
dev: false
/@octokit/plugin-rest-endpoint-methods@10.0.1(@octokit/core@5.0.1):
resolution: {integrity: sha512-fgS6HPkPvJiz8CCliewLyym9qAx0RZ/LKh3sATaPfM41y/O2wQ4Z9MrdYeGPVh04wYmHFmWiGlKPC7jWVtZXQA==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '>=5'
dependencies:
'@octokit/core': 5.0.1
'@octokit/types': 12.0.0
dev: false
/@octokit/request-error@5.0.1:
resolution: {integrity: sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==}
engines: {node: '>= 18'}
dependencies:
'@octokit/types': 12.0.0
deprecation: 2.3.1
once: 1.4.0
dev: false
/@octokit/request@8.1.4:
resolution: {integrity: sha512-M0aaFfpGPEKrg7XoA/gwgRvc9MSXHRO2Ioki1qrPDbl1e9YhjIwVoHE7HIKmv/m3idzldj//xBujcFNqGX6ENA==}
engines: {node: '>= 18'}
dependencies:
'@octokit/endpoint': 9.0.1
'@octokit/request-error': 5.0.1
'@octokit/types': 12.0.0
is-plain-object: 5.0.0
universal-user-agent: 6.0.0
dev: false
/@octokit/types@12.0.0:
resolution: {integrity: sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==}
dependencies:
'@octokit/openapi-types': 19.0.0
dev: false
/@opentelemetry/api-logs@0.39.1:
resolution: {integrity: sha512-9BJ8lMcOzEN0lu+Qji801y707oFO4xT3db6cosPvl+k7ItUHKN5ofWqtSbM9gbt1H4JJ/4/2TVrqI9Rq7hNv6Q==}
engines: {node: '>=14'}
@ -12462,6 +12613,11 @@ packages:
'@vercel/edge-config-fs': 0.1.0
dev: false
/@vercel/ncc@0.38.0:
resolution: {integrity: sha512-B4YKZMm/EqMptKSFyAq4q2SlgJe+VCmEH6Y8gf/E1pTlWbsUJpuH1ymik2Ex3aYO5mCWwV1kaSYHSQOT8+4vHA==}
hasBin: true
dev: true
/@vitejs/plugin-react@3.1.0(vite@4.4.10):
resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==}
engines: {node: ^14.18.0 || >=16.0.0}
@ -13298,6 +13454,10 @@ packages:
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
/before-after-hook@2.2.3:
resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
dev: false
/better-opn@2.1.1:
resolution: {integrity: sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==}
engines: {node: '>8.0.0'}
@ -14630,6 +14790,10 @@ packages:
invariant: 2.2.4
prop-types: 15.8.1
/deprecation@2.3.1:
resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
dev: false
/dequal@2.0.3:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'}
@ -24139,6 +24303,12 @@ packages:
engines: {node: '>=12'}
dev: true
/tmp-promise@3.0.3:
resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==}
dependencies:
tmp: 0.2.1
dev: false
/tmp@0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@ -24146,6 +24316,13 @@ packages:
os-tmpdir: 1.0.2
dev: false
/tmp@0.2.1:
resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
engines: {node: '>=8.17.0'}
dependencies:
rimraf: 3.0.2
dev: false
/tmpl@1.0.5:
resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
@ -24601,6 +24778,11 @@ packages:
safe-buffer: 5.2.1
dev: false
/tunnel@0.0.6:
resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==}
engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'}
dev: false
/turbo-darwin-64@1.10.14:
resolution: {integrity: sha512-I8RtFk1b9UILAExPdG/XRgGQz95nmXPE7OiGb6ytjtNIR5/UZBS/xVX/7HYpCdmfriKdVwBKhalCoV4oDvAGEg==}
cpu: [x64]
@ -25006,6 +25188,10 @@ packages:
unist-util-visit-parents: 5.1.3
dev: false
/universal-user-agent@6.0.0:
resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==}
dev: false
/universalify@0.1.2:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
engines: {node: '>= 4.0.0'}

View file

@ -6,3 +6,4 @@ packages:
- 'docs'
- 'crates/sync/example/web'
- 'scripts'
- '.github/actions/*'