Skip to content

fix: only export runtime config once, not every upgrade #133

fix: only export runtime config once, not every upgrade

fix: only export runtime config once, not every upgrade #133

Workflow file for this run

name: Dev Candidate Build
on:
workflow_dispatch:
push:
branches: [dev]
paths-ignore:
- '**.md'
- 'docs/**'
- 'media/**'
- 'logs/**'
- '.gitignore'
- 'LICENSE*'
concurrency:
group: ci-${{ github.ref_name }}
cancel-in-progress: false
jobs:
# ── Detect what changed to skip unnecessary image builds ──
changes:
name: Detect Changes
runs-on: ubuntu-latest
outputs:
image: ${{ steps.filter.outputs.image }}
install: ${{ steps.filter.outputs.install }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
image:
- 'docker/Dockerfile'
- 'docker/proxy/**'
- 'docker/gateway/**'
- 'docker/apphub/**'
- 'docker/scripts/**'
- 'docker/supervisord.conf'
- 'docker/crontab'
- 'docker/deployment/**'
- 'console/**'
- 'apphub/**'
- 'version.json'
install:
- 'install/**'
- 'scripts/**'
- 'mirrors.json'
- 'CHANGELOG.md'
- 'docker/docker-compose.yml'
- 'docker/docker-compose.dev.yml'
# ── Determine dev candidate tags ──
meta:
name: Determine Build Meta
runs-on: ubuntu-latest
outputs:
channel: ${{ steps.meta.outputs.channel }}
version: ${{ steps.meta.outputs.version }}
edition_key: ${{ steps.meta.outputs.edition_key }}
tags: ${{ steps.meta.outputs.tags }}
steps:
- uses: actions/checkout@v4
- id: meta
run: |
VERSION=$(jq -r '.version' version.json)
EDITION=$(jq -r '.edition_key' version.json)
CHANNEL=dev
# Push only dev and <version>-dev moving tags during test phase.
# SHA-tagged images are omitted to avoid accumulating hundreds of
# untagged images on Docker Hub.
TAGS="websoft9dev/websoft9:dev,websoft9dev/websoft9:${VERSION}-dev"
echo "channel=$CHANNEL" >> $GITHUB_OUTPUT
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "edition_key=$EDITION" >> $GITHUB_OUTPUT
echo "tags=$TAGS" >> $GITHUB_OUTPUT
echo "✅ Dev candidate | Version: $VERSION | Tags: $TAGS"
# ── Build, scan, push dev image ──
build-and-push:
name: Build & Push Image
needs: [meta, changes]
if: needs.changes.outputs.image == 'true'
uses: ./.github/workflows/docker-build.yml
with:
push: true
platforms: linux/amd64
tags: ${{ needs.meta.outputs.tags }}
appstore_channel: ${{ needs.meta.outputs.channel }}
no_cache: true
secrets: inherit
# ── Smoke test using the dev tag ──
smoke-test:
name: Smoke Test
needs: [meta, changes, build-and-push]
if: needs.changes.outputs.image == 'true'
uses: ./.github/workflows/smoke-test.yml
with:
image: websoft9dev/websoft9:dev
# ── Publish dev artifacts to R2 without creating a formal release ──
upload-artifacts:
name: Upload Dev Artifacts
needs: [meta, changes, build-and-push]
if: |
always() &&
!cancelled() &&
(needs.changes.outputs.install == 'true' || needs.build-and-push.result == 'success')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Create dev distribution bundles
run: |
VERSION="${{ needs.meta.outputs.version }}"
EDITION_KEY="${{ needs.meta.outputs.edition_key }}"
CHANNEL="${{ needs.meta.outputs.channel }}"
TAGS="${{ needs.meta.outputs.tags }}"
GENERATED_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)
COMPOSE_FILE="docker-compose.dev.yml"
SHORT_SHA="${GITHUB_SHA:0:8}"
mkdir -p release-assets r2-artifacts websoft9
jq \
--arg version "$VERSION" \
--arg edition_key "$EDITION_KEY" \
--arg channel "$CHANNEL" \
'.version = $version | .edition_key = $edition_key | .channel = $channel' \
version.json > staged-version.json
cp -r docker websoft9/
cp -r scripts websoft9/
cp -r install websoft9/
cp staged-version.json websoft9/version.json
cp CHANGELOG.md websoft9/
cp mirrors.json websoft9/
zip -r "websoft9-${VERSION}-${SHORT_SHA}.zip" websoft9
cp "websoft9-${VERSION}-${SHORT_SHA}.zip" release-assets/
cp "release-assets/websoft9-${VERSION}-${SHORT_SHA}.zip" release-assets/websoft9-dev.zip
bash install/build-bundle.sh --channel "$CHANNEL" install/dist
cp install/dist/install.sh r2-artifacts/install.sh
cp install/dist/uninstall.sh r2-artifacts/uninstall.sh
cp install/install_docker.sh r2-artifacts/install_docker.sh
cp "docker/${COMPOSE_FILE}" "r2-artifacts/${COMPOSE_FILE}"
cp staged-version.json r2-artifacts/version.json
cp CHANGELOG.md r2-artifacts/CHANGELOG.md
cp mirrors.json r2-artifacts/mirrors.json
cp staged-version.json release-assets/version.json
cp CHANGELOG.md release-assets/CHANGELOG.md
cp mirrors.json release-assets/mirrors.json
jq -n \
--arg schema_version "1" \
--arg product "websoft9" \
--arg channel "$CHANNEL" \
--arg version "$VERSION" \
--arg edition_key "$EDITION_KEY" \
--arg git_sha "$GITHUB_SHA" \
--arg generated_at "$GENERATED_AT" \
--arg repository "websoft9dev/websoft9" \
--arg default_tag "dev" \
--arg version_tag "${VERSION}-dev" \
--arg image_tags "$TAGS" \
'{
schema_version: ($schema_version | tonumber),
product: $product,
channel: $channel,
version: $version,
edition_key: $edition_key,
git_sha: $git_sha,
generated_at: $generated_at,
install: {
compose_file: $compose_file,
install_script: "install.sh",
uninstall_script: "uninstall.sh",
docker_install_script: "install_docker.sh",
changelog_file: "CHANGELOG.md",
version_file: "version.json",
mirrors_file: "mirrors.json",
checksum_file: "SHA256SUMS"
},
image: {
repository: $repository,
default_tag: $default_tag,
version_tag: $version_tag,
image_tags: ($image_tags | split(","))
},
distribution: {
bundle_file: ("websoft9-" + $version + "-" + $git_sha[0:8] + ".zip"),
alias_bundle_file: "websoft9-dev.zip"
}
}' \
--arg compose_file "$COMPOSE_FILE" > manifest.json
cp manifest.json r2-artifacts/manifest.json
cp manifest.json release-assets/manifest.json
grep '^OPT_CHANNEL="dev"' install/dist/install.sh
jq -e '.channel == "dev" and .install.compose_file == "docker-compose.dev.yml"' manifest.json >/dev/null
(
cd r2-artifacts
sha256sum \
install.sh \
uninstall.sh \
install_docker.sh \
"$COMPOSE_FILE" \
version.json \
CHANGELOG.md \
mirrors.json \
manifest.json > SHA256SUMS
)
(
cd release-assets
sha256sum \
"websoft9-${VERSION}-${SHORT_SHA}.zip" \
websoft9-dev.zip \
version.json \
CHANGELOG.md \
mirrors.json \
manifest.json > SHA256SUMS
)
echo "✅ Dev bundles created: websoft9-${VERSION}-${SHORT_SHA}.zip"
- name: Upload to Cloudflare R2
uses: ryand56/r2-upload-action@latest
with:
r2-account-id: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
r2-access-key-id: ${{ secrets.CLOUDFLARE_R2_SECRET_ID }}
r2-secret-access-key: ${{ secrets.CLOUDFLARE_R2_SECRET_KEY }}
r2-bucket: artifact
source-dir: r2-artifacts
destination-dir: ./websoft9/${{ needs.meta.outputs.channel }}
- name: Purge Cloudflare Cache
uses: jakejarvis/cloudflare-purge-action@master
env:
CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE_ID }}
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
PURGE_URLS: >-
["https://artifact.websoft9.com/websoft9/${{ needs.meta.outputs.channel }}/install.sh",
"https://artifact.websoft9.com/websoft9/${{ needs.meta.outputs.channel }}/uninstall.sh",
"https://artifact.websoft9.com/websoft9/${{ needs.meta.outputs.channel }}/install_docker.sh",
"https://artifact.websoft9.com/websoft9/${{ needs.meta.outputs.channel }}/docker-compose.yml",
"https://artifact.websoft9.com/websoft9/${{ needs.meta.outputs.channel }}/manifest.json",
"https://artifact.websoft9.com/websoft9/${{ needs.meta.outputs.channel }}/version.json",
"https://artifact.websoft9.com/websoft9/${{ needs.meta.outputs.channel }}/SHA256SUMS"]
- name: Publish Dev GitHub prerelease
uses: softprops/action-gh-release@v2
with:
tag_name: dev-artifacts
target_commitish: dev
name: Dev Artifacts
prerelease: true
draft: false
generate_release_notes: false
make_latest: false
files: |
release-assets/websoft9-${{ needs.meta.outputs.version }}-${GITHUB_SHA:0:8}.zip
release-assets/websoft9-dev.zip
release-assets/manifest.json
release-assets/SHA256SUMS
release-assets/version.json
release-assets/CHANGELOG.md
# ── Docker Hub description is maintained by the release workflow ──
dockerhub-description:
name: Update DockerHub README
runs-on: ubuntu-latest
needs: build-and-push
if: false
steps:
- uses: actions/checkout@v4
- uses: peter-evans/dockerhub-description@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
repository: websoft9dev/websoft9
readme-filepath: docker/README.md