3 Commits
Author SHA1 Message Date
kawa 3ed8f5683f Fixed publish script+added options to separate binaries publishing.
Bumped package.json to 2.0.0
2026-08-13 08:48:34 +02:00
kawa fd0314549b Merge pull request 'Packaging/release scripts' (#1) from packaging/release-scripts into main
Reviewed-on: #1
2026-08-12 17:38:11 +02:00
kawa 89771b2555 docs: improve README with clearer structure and examples
Reorganize installation and build instructions with separate sections for
web, desktop, and Docker. Add quick start commands and move detailed
packaging info to PACKAGING.md.
2026-08-12 17:02:05 +02:00
4 changed files with 91 additions and 53 deletions
+21 -24
View File
@@ -1,38 +1,35 @@
# Motionity # Motionity
This is a fork of the original project aiming to fix issues and add features. Web-based motion graphics editor with keyframing, masking, filters and text animations.
## Running it This is a fork of the original [Motionity](https://github.com/alyssaxuu/motionity) by [@alyssaxuu](https://github.com/alyssaxuu), with bug fixes and enhancements.
## Quick Start
**Web (localhost only):**
```bash ```bash
npm install # ffmpeg.wasm is vendored out of node_modules, so this is required npm install
npm run vendor # downloads the third-party libraries into src/vendor/ npm run vendor
npm start # http://127.0.0.1:8080 npm start # http://127.0.0.1:8080
``` ```
Three packaged distributions are available — desktop (Windows `.exe`, Linux **Desktop:**
AppImage and Flatpak), a Docker image, and a bare-metal install. Build
instructions for all of them are in [PACKAGING.md](PACKAGING.md).
```bash ```bash
npm run dev # desktop app from source npm install
npm run dist:win # Windows installer + portable exe npm run vendor
npm run dist:linux # AppImage + Flatpak npm run dev # Electron app
npm run docker:build # container image
``` ```
## Releasing **Docker:**
```bash
```powershell npm run docker:build
./scripts/build-release.ps1 # installers + SHA256SUMS.txt in dist/ npm run docker:run # http://localhost:8080
./scripts/publish.ps1 -PublishRelease # + image push and Gitea release upload
``` ```
`build-release.ps1` needs no credentials. `publish.ps1` needs a Gitea token with Full build instructions (Windows installers, Linux AppImage/Flatpak) in [PACKAGING.md](PACKAGING.md).
package read/write (image push) and `write:repository` (release upload), read
from `$env:GITEA_TOKEN` or prompted for. `-BinariesOnly -NoBinaryBuild` retries a
failed upload without rebuilding.
One rule applies to every target: browsers expose WebCodecs (the fast exporter) ## Notes
and IndexedDB (project saving) only in a secure context. `http://localhost`
qualifies; a plain-HTTP LAN address does not. Serve it over TLS anywhere else. - `ffmpeg.wasm` is vendored; `npm install` + `npm run vendor` are required
- WebCodecs and IndexedDB only work in secure context (`http://localhost` OK, plain HTTP over LAN is not)
- Serve over TLS for remote access
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"name": "motionity", "name": "motionity",
"productName": "Motionity", "productName": "Motionity",
"version": "1.0.0", "version": "2.0.0",
"description": "Web-based motion graphics editor with keyframing, masking, filters and text animations", "description": "Web-based motion graphics editor with keyframing, masking, filters and text animations",
"license": "MIT", "license": "MIT",
"author": "Kawa", "author": "Kawa",
+35 -12
View File
@@ -36,14 +36,19 @@
./scripts/build-release.ps1 -Targets win -Tag v1.1.0 ./scripts/build-release.ps1 -Targets win -Tag v1.1.0
Windows installers only, named v1.1.0. Windows installers only, named v1.1.0.
.EXAMPLE
./scripts/build-release.ps1 -Targets win,linux-appimage
Windows installers plus the Linux AppImage — no Flatpak.
.EXAMPLE .EXAMPLE
./scripts/build-release.ps1 -SkipVendor -SkipDeps ./scripts/build-release.ps1 -SkipVendor -SkipDeps
Reuse src/vendor/ and node_modules as they are — the fast rebuild. Reuse src/vendor/ and node_modules as they are — the fast rebuild.
#> #>
[CmdletBinding()] [CmdletBinding()]
param( param(
# Platforms to package. "win" is NSIS + portable, "linux" is AppImage + Flatpak. # Platforms to package. "win" is NSIS + portable; "linux-appimage" and
[ValidateSet("win", "linux")] # "linux-flatpak" are the two Linux bundles, and "linux" is shorthand for both.
[ValidateSet("win", "linux", "linux-appimage", "linux-flatpak")]
[string[]]$Targets = @("win", "linux"), [string[]]$Targets = @("win", "linux"),
# Version used in the artifact names. Defaults to v<package.json version>, # Version used in the artifact names. Defaults to v<package.json version>,
@@ -64,11 +69,15 @@ param(
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
function Invoke-Checked { function Invoke-Checked {
param([Parameter(Mandatory)][string]$Exe, [Parameter(Mandatory)][string[]]$Args) # NB: the param is $CmdArgs, not $Args. $Args is an automatic variable in
Write-Host " > $Exe $($Args -join ' ')" -ForegroundColor DarkGray # PowerShell; a param of that name never binds the passed array (it stays the
& $Exe @Args # function's own empty $args), so `& $Exe @Args` would run the exe with no
# arguments — e.g. bare `npm`, which just prints usage and exits 1.
param([Parameter(Mandatory)][string]$Exe, [Parameter(Mandatory)][string[]]$CmdArgs)
Write-Host " > $Exe $($CmdArgs -join ' ')" -ForegroundColor DarkGray
& $Exe @CmdArgs
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
throw "'$Exe $($Args -join ' ')' failed with exit code $LASTEXITCODE." throw "'$Exe $($CmdArgs -join ' ')' failed with exit code $LASTEXITCODE."
} }
} }
@@ -101,11 +110,20 @@ try {
Write-Host " output : $distDir" Write-Host " output : $distDir"
Write-Host "" Write-Host ""
# Expand "linux" to its two concrete bundles and drop duplicates, so the rest
# of the script only ever deals with win / linux-appimage / linux-flatpak.
$resolvedTargets = @()
foreach ($t in $Targets) {
if ($t -eq "linux") { $resolvedTargets += "linux-appimage", "linux-flatpak" }
else { $resolvedTargets += $t }
}
$resolvedTargets = @($resolvedTargets | Select-Object -Unique)
# electron-builder produces AppImage and Flatpak with Linux-only tooling # electron-builder produces AppImage and Flatpak with Linux-only tooling
# (appimagetool, flatpak-builder). Warned rather than blocked: the same script # (appimagetool, flatpak-builder). Warned rather than blocked: the same script
# runs under pwsh on a Linux box or in WSL, which is where that target belongs. # runs under pwsh on a Linux box or in WSL, which is where that target belongs.
if ($Targets -contains "linux" -and $env:OS -eq "Windows_NT") { if (($resolvedTargets -like "linux-*") -and $env:OS -eq "Windows_NT") {
Write-Warning "the linux target needs a Linux host or WSL — electron-builder cannot produce AppImage or Flatpak on Windows (PACKAGING.md has the WSL setup)." Write-Warning "the Linux targets need a Linux host or WSL — electron-builder cannot produce AppImage or Flatpak on Windows (PACKAGING.md has the WSL setup)."
} }
if ($Clean) { if ($Clean) {
@@ -161,7 +179,7 @@ try {
throw 'electron-builder not found in node_modules — run "npm ci" (or drop -SkipDeps).' throw 'electron-builder not found in node_modules — run "npm ci" (or drop -SkipDeps).'
} }
foreach ($target in $Targets) { foreach ($target in $resolvedTargets) {
Write-Host "Packaging $target..." -ForegroundColor Cyan Write-Host "Packaging $target..." -ForegroundColor Cyan
# --publish never: electron-builder otherwise tries to upload to whatever # --publish never: electron-builder otherwise tries to upload to whatever
@@ -175,10 +193,15 @@ try {
"-c.portable.artifactName=$(Get-ArtifactName "$prefix-win-x64-portable")" "-c.portable.artifactName=$(Get-ArtifactName "$prefix-win-x64-portable")"
) )
} }
"linux" { "linux-appimage" {
$builderArgs = @( $builderArgs = @(
"--linux", "AppImage", "flatpak", "--publish", "never", "--linux", "AppImage", "--publish", "never",
"-c.appImage.artifactName=$(Get-ArtifactName "$prefix-linux-x86_64")", "-c.appImage.artifactName=$(Get-ArtifactName "$prefix-linux-x86_64")"
)
}
"linux-flatpak" {
$builderArgs = @(
"--linux", "flatpak", "--publish", "never",
"-c.flatpak.artifactName=$(Get-ArtifactName "$prefix-linux-x86_64")" "-c.flatpak.artifactName=$(Get-ArtifactName "$prefix-linux-x86_64")"
) )
} }
+33 -15
View File
@@ -14,8 +14,10 @@
instead (creating the release if it does not exist). instead (creating the release if it does not exist).
-BinariesOnly ships just the installers: no docker build, no docker login, no -BinariesOnly ships just the installers: no docker build, no docker login, no
image push, and the release upload is implied. That is also the mode to use on image push, and the release upload is implied. It takes the target list to
a Linux host or in WSL, where the AppImage and Flatpak targets actually build. build (win, linux-appimage, linux-flatpak — comma-separated) and that list
overrides -Targets. The Linux targets need a Linux host or WSL, which is where
-BinariesOnly linux-appimage,linux-flatpak belongs.
Credentials are read, in order of precedence: Credentials are read, in order of precedence:
1. -Username / -Password parameters 1. -Username / -Password parameters
@@ -35,13 +37,19 @@
Full release: push the image and attach every dist/ installer to release v1.1.0. Full release: push the image and attach every dist/ installer to release v1.1.0.
.EXAMPLE .EXAMPLE
./scripts/publish.ps1 -BinariesOnly -Targets win -Tag v1.1.0 ./scripts/publish.ps1 -BinariesOnly win -Tag v1.1.0
Windows installers only — build them and attach them to release v1.1.0. Docker Windows installers only — build them and attach them to release v1.1.0. Docker
is never invoked, so this works with Docker Desktop stopped. is never invoked, so this works with Docker Desktop stopped.
.EXAMPLE .EXAMPLE
./scripts/publish.ps1 -BinariesOnly -NoBinaryBuild -Tag v1.1.0 ./scripts/publish.ps1 -BinariesOnly win,linux-appimage -Tag v1.1.0
Retry a failed upload: attach the installers already in dist/ without rebuilding. Windows installers plus the Linux AppImage (no Flatpak), attached to v1.1.0.
.EXAMPLE
./scripts/publish.ps1 -BinariesOnly win -NoBinaryBuild -Tag v1.1.0
Retry a failed upload: attach the installers already in dist/ without rebuilding
(the target list is required syntactically but ignored — every dist/ installer
for the tag is uploaded regardless).
.EXAMPLE .EXAMPLE
./scripts/publish.ps1 -NoBinaries ./scripts/publish.ps1 -NoBinaries
@@ -92,8 +100,8 @@ param(
# Skip building the desktop installers. # Skip building the desktop installers.
[switch]$NoBinaries, [switch]$NoBinaries,
# Forwarded to build-release.ps1. # Forwarded to build-release.ps1. "linux" is shorthand for both Linux bundles.
[ValidateSet("win", "linux")] [ValidateSet("win", "linux", "linux-appimage", "linux-flatpak")]
[string[]]$Targets = @("win", "linux"), [string[]]$Targets = @("win", "linux"),
[switch]$SkipVendor, [switch]$SkipVendor,
@@ -103,7 +111,10 @@ param(
# Ship only the installers: no docker build, login or push. Implies # Ship only the installers: no docker build, login or push. Implies
# -PublishRelease, since building alone is what build-release.ps1 already does. # -PublishRelease, since building alone is what build-release.ps1 already does.
[switch]$BinariesOnly, # Takes the target list to build (comma-separated), which overrides -Targets:
# -BinariesOnly win,linux-appimage
[ValidateSet("win", "linux-appimage", "linux-flatpak")]
[string[]]$BinariesOnly,
# Attach the installers to the Gitea release for $Tag, creating the release if # Attach the installers to the Gitea release for $Tag, creating the release if
# it is missing. # it is missing.
@@ -122,11 +133,13 @@ param(
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
function Invoke-Checked { function Invoke-Checked {
param([Parameter(Mandatory)][string]$Exe, [Parameter(Mandatory)][string[]]$Args) # $CmdArgs, not $Args: $Args is a PowerShell automatic variable and never
Write-Host " > $Exe $($Args -join ' ')" -ForegroundColor DarkGray # binds the passed array, so `& $Exe @Args` would run the exe bare.
& $Exe @Args param([Parameter(Mandatory)][string]$Exe, [Parameter(Mandatory)][string[]]$CmdArgs)
Write-Host " > $Exe $($CmdArgs -join ' ')" -ForegroundColor DarkGray
& $Exe @CmdArgs
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
throw "'$Exe $($Args -join ' ')' failed with exit code $LASTEXITCODE." throw "'$Exe $($CmdArgs -join ' ')' failed with exit code $LASTEXITCODE."
} }
} }
@@ -283,20 +296,25 @@ $repoRoot = Split-Path -Parent $PSScriptRoot
Push-Location $repoRoot Push-Location $repoRoot
try { try {
# --- Mode resolution ------------------------------------------------------ # --- Mode resolution ------------------------------------------------------
if ($BinariesOnly -and $NoBinaries) { # -BinariesOnly is a target list, so its mere presence (a non-empty array) is
# what selects the mode.
$binariesOnlyMode = $BinariesOnly.Count -gt 0
if ($binariesOnlyMode -and $NoBinaries) {
throw "-BinariesOnly and -NoBinaries cancel each other out — pick one." throw "-BinariesOnly and -NoBinaries cancel each other out — pick one."
} }
if ($NoBinaryBuild -and $NoBinaries) { if ($NoBinaryBuild -and $NoBinaries) {
throw "-NoBinaryBuild reuses the build that -NoBinaries skips entirely — pick one." throw "-NoBinaryBuild reuses the build that -NoBinaries skips entirely — pick one."
} }
if ($BinariesOnly) { if ($binariesOnlyMode) {
# Nothing to build, log into or push on the container side, and uploading # Nothing to build, log into or push on the container side, and uploading
# is the whole point (build-release.ps1 alone covers "just build them"). # is the whole point (build-release.ps1 alone covers "just build them").
$NoBuild = $true $NoBuild = $true
$SkipLogin = $true $SkipLogin = $true
$PublishRelease = $true $PublishRelease = $true
# The targets named on -BinariesOnly are what to build.
$Targets = $BinariesOnly
} }
$pushImage = -not $BinariesOnly $pushImage = -not $binariesOnlyMode
if (-not $ReleaseRepo) { $ReleaseRepo = "$Owner/$Repo" } if (-not $ReleaseRepo) { $ReleaseRepo = "$Owner/$Repo" }
if (-not $ApiBase) { $ApiBase = "https://$Registry" } if (-not $ApiBase) { $ApiBase = "https://$Registry" }