forked from 1b-agent/opencadstudio-upstream
Fix web folder paths and allow main-only web hotfix deployment
This commit is contained in:
1 parent
a43fb253f6
commit
95bad2a3b2
5 files changed
+69
-11
No files matched your search
@@ -13,6 +13,11 @@ on:
|
||||
required: true
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_main:
|
||||
description: Build a web hotfix from main without changing the release tag
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -38,6 +43,7 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
RELEASE_TAG: ${{ inputs.tag || github.event.release.tag_name }}
|
||||
RELEASE_COMMIT: ${{ inputs.commit }}
|
||||
BUILD_MAIN: ${{ github.event_name == 'workflow_dispatch' && inputs.build_main }}
|
||||
run: |
|
||||
if [ -z "$RELEASE_TAG" ]; then
|
||||
RELEASE_TAG=$(gh release view --repo "$GITHUB_REPOSITORY" --json tagName --jq .tagName)
|
||||
@@ -47,6 +53,13 @@ jobs:
|
||||
echo "::error::Release tag and commit do not match"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$BUILD_MAIN" = "true" ]; then
|
||||
if [ "$GITHUB_REF" != "refs/heads/main" ]; then
|
||||
echo "::error::Web hotfixes must run on main"
|
||||
exit 1
|
||||
fi
|
||||
COMMIT="$GITHUB_SHA"
|
||||
fi
|
||||
echo "tag=$RELEASE_TAG" >> "$GITHUB_OUTPUT"
|
||||
echo "commit=$COMMIT" >> "$GITHUB_OUTPUT"
|
||||
|
||||
@@ -61,6 +74,7 @@ jobs:
|
||||
env:
|
||||
RELEASE_TAG: ${{ steps.source.outputs.tag }}
|
||||
run: |
|
||||
git merge-base --is-ancestor "$RELEASE_TAG" HEAD
|
||||
if [ -f scripts/release.py ]; then
|
||||
python3 scripts/release.py versions --tag "$RELEASE_TAG"
|
||||
else
|
||||
|
||||
+4
-1
@@ -31,4 +31,7 @@ To preview release notes, manually run **Weekly release** on `main` with
|
||||
**publish** unchecked. Check **publish** to release immediately. Rerunning
|
||||
within the same week reuses the original tag and commit. To rebuild just a
|
||||
failed target, use GitHub's **Re-run failed jobs**. Manual web deployment
|
||||
always uses the latest published release rather than unreleased `main`.
|
||||
defaults to the latest published release. For a web hotfix, run **Deploy web**
|
||||
on `main` with **build_main** checked. The commit must descend from that release
|
||||
and keep its package version; `/app/release.json` records the actual build commit
|
||||
without moving the release tag.
|
||||
@@ -8,6 +8,7 @@ import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import textwrap
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
@@ -15,6 +16,36 @@ import release
|
||||
|
||||
|
||||
class ReleaseTests(unittest.TestCase):
|
||||
def test_web_source_selection(self):
|
||||
workflow = (Path(__file__).resolve().parents[1] / ".github/workflows/pages.yml").read_text()
|
||||
source = workflow.split(" - name: Resolve release source\n", 1)[1]
|
||||
script = textwrap.dedent(source.split(" run: |\n", 1)[1].split("\n - uses:", 1)[0])
|
||||
mock_gh = 'gh() { if [ "$1" = release ]; then echo v2026.37; else echo release-sha; fi; }\n'
|
||||
cases = (
|
||||
({}, "release-sha", None),
|
||||
({"RELEASE_TAG": "v2026.37", "RELEASE_COMMIT": "release-sha"}, "release-sha", None),
|
||||
({"RELEASE_COMMIT": "wrong-sha"}, None, "Release tag and commit do not match"),
|
||||
({"BUILD_MAIN": "true"}, "main-sha", None),
|
||||
({"BUILD_MAIN": "true", "GITHUB_REF": "refs/heads/other"}, None, "Web hotfixes must run on main"),
|
||||
)
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
output = Path(temp) / "output"
|
||||
for overrides, commit, error in cases:
|
||||
with self.subTest(overrides=overrides):
|
||||
output.write_text("")
|
||||
result = subprocess.run(["bash", "-e", "-c", mock_gh + script], text=True, capture_output=True, env={
|
||||
**os.environ, "GITHUB_REPOSITORY": "owner/repo", "GITHUB_REF": "refs/heads/main",
|
||||
"GITHUB_SHA": "main-sha", "GITHUB_OUTPUT": str(output),
|
||||
"RELEASE_TAG": "", "RELEASE_COMMIT": "", "BUILD_MAIN": "false", **overrides,
|
||||
})
|
||||
if error:
|
||||
self.assertNotEqual(result.returncode, 0)
|
||||
self.assertIn(error, result.stdout)
|
||||
self.assertEqual(output.read_text(), "")
|
||||
else:
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
self.assertEqual(output.read_text(), f"tag=v2026.37\ncommit={commit}\n")
|
||||
|
||||
def test_build_metadata(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
binary = str(Path(temp) / "build-script")
|
||||
|
||||
@@ -18,3 +18,4 @@ The drawing screenshot also supplies the social preview; website image URLs chan
|
||||
GitHub Pages runs on release publication, a call from the weekly release workflow,
|
||||
or a manual run. Commits and pushes do not start workflows. Deployments use website
|
||||
files from `main` and build the app from the release, recording both sources separately.
|
||||
Manual runs can select **build_main** to publish a web hotfix; see `docs/releases.md`.
|
||||
+19
-10
@@ -249,16 +249,25 @@ impl OpenCADStudio {
|
||||
.map_or(1, |h| h.show_solid_history),
|
||||
}
|
||||
},
|
||||
crate::ui::window::options::Folders {
|
||||
config: crate::config::config_dir()
|
||||
.map(|p| p.display().to_string()),
|
||||
plot_styles: crate::io::plot_style::plot_styles_dir()
|
||||
.ok()
|
||||
.map(|p| p.display().to_string()),
|
||||
plugins: crate::plugin::external::plugins_dir()
|
||||
.map(|p| p.display().to_string()),
|
||||
autosave: crate::config::config_dir()
|
||||
.map(|_| std::env::temp_dir().display().to_string()),
|
||||
{
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
crate::ui::window::options::Folders {
|
||||
config: crate::config::config_dir()
|
||||
.map(|p| p.display().to_string()),
|
||||
plot_styles: crate::io::plot_style::plot_styles_dir()
|
||||
.ok()
|
||||
.map(|p| p.display().to_string()),
|
||||
plugins: crate::plugin::external::plugins_dir()
|
||||
.map(|p| p.display().to_string()),
|
||||
autosave: crate::config::config_dir()
|
||||
.map(|_| std::env::temp_dir().display().to_string()),
|
||||
}
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
crate::ui::window::options::Folders::default()
|
||||
}
|
||||
},
|
||||
self.double_click_block_refedit,
|
||||
self.double_click_block_attedit,
|
||||
|
||||
Reference in new issue
Block a user