release.yaml (all three jobs), sites.yaml and release-assets.yaml run the same cold production build that the review jobs do, so they get the same pre-install check. The header now says what the check rules out (an undersized box) and what it does not (two jobs sharing one box), so the MemAvailable warning is not read as a gate.
223 lines
8.4 KiB
YAML
223 lines
8.4 KiB
YAML
name: Release assets
|
|
run-name: Building and uploading the release assets
|
|
|
|
# Builds the downloadable artefacts for an existing release and uploads them.
|
|
#
|
|
# The release job cuts the tag before it builds, so a failure anywhere between
|
|
# the semantic-release step and the asset upload leaves a published release with
|
|
# no files - and that job cannot simply be re-run, because semantic-release
|
|
# refuses once the tag exists. This workflow rebuilds the artefacts from the tag
|
|
# and attaches them, so the release can be completed without cutting a new one.
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: 'Release tag to build and upload (blank = the latest release)'
|
|
required: false
|
|
default: ''
|
|
|
|
env:
|
|
NODE_VERSION: '24.5.0'
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
assets:
|
|
runs-on: ubuntu-latest
|
|
# Two runs uploading the same asset names would race the delete-then-upload
|
|
# below.
|
|
concurrency:
|
|
group: release-assets
|
|
cancel-in-progress: false
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
- name: Check runner size
|
|
# Builds the same frontend as the release jobs; an undersized runner
|
|
# fails inside the build - see the script.
|
|
run: bash .gitea/scripts/check-runner-memory.sh
|
|
- uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
|
|
- name: Write .npmrc file
|
|
run: |
|
|
printf '%s\n' "$NPMRC" > "$RUNNER_TEMP/npmrc"
|
|
echo "legacy-peer-deps=true" >> "$RUNNER_TEMP/npmrc"
|
|
echo "NPM_CONFIG_USERCONFIG=$RUNNER_TEMP/npmrc" >> "$GITHUB_ENV"
|
|
shell: bash
|
|
env:
|
|
NPMRC: ${{ secrets.NPMRC }}
|
|
|
|
- name: Install system packages
|
|
# jq parses the release JSON below, so it is installed before the tag
|
|
# resolve.
|
|
run: |
|
|
apt-get update
|
|
apt-get install -y zip jq
|
|
|
|
- name: Resolve the release tag
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
REQUESTED_TAG: ${{ inputs.tag }}
|
|
run: |
|
|
set -euo pipefail
|
|
AUTH_HEADER="Authorization: token $GITEA_TOKEN"
|
|
BASE="${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}"
|
|
|
|
if [ -n "${REQUESTED_TAG}" ]; then
|
|
TAG="${REQUESTED_TAG}"
|
|
# Fail here rather than after a ten-minute build if the tag is not
|
|
# cut yet or has no release.
|
|
curl --fail-with-body -sS -H "$AUTH_HEADER" "$BASE/releases/tags/${TAG}" > /dev/null
|
|
else
|
|
TAG=$(curl --fail-with-body -sS -H "$AUTH_HEADER" "$BASE/releases/latest" | jq -r '.tag_name')
|
|
fi
|
|
echo "Building assets for ${TAG}"
|
|
echo "TAG=${TAG}" >> "$GITHUB_ENV"
|
|
|
|
- name: Check out the tag
|
|
run: |
|
|
set -euo pipefail
|
|
git fetch --force --tags origin "+refs/tags/${TAG}:refs/tags/${TAG}"
|
|
git checkout --force "refs/tags/${TAG}"
|
|
|
|
- name: Install the SASjs CLI the tag pins
|
|
run: |
|
|
cd sas
|
|
CLI_VERSION=$(node -p "require('./package.json').dependencies['@sasjs/cli']")
|
|
npm i -g "@sasjs/cli@${CLI_VERSION}"
|
|
|
|
- name: Frontend build
|
|
run: |
|
|
cd client
|
|
# Decrypt and Install sheet
|
|
echo "$SHEET_PWD" | gpg --batch --yes --passphrase-fd 0 ./libraries/sheet-crypto.tgz.gpg
|
|
npm ci
|
|
# client install scripts are off (client/.npmrc); the generator that
|
|
# creates src/environments/version.ts runs explicitly
|
|
npm run postinstall
|
|
npm i webpack
|
|
npm run build
|
|
shell: bash
|
|
env:
|
|
SHEET_PWD: ${{ secrets.SHEET_PWD }}
|
|
|
|
- name: Build SAS9 EBI Release
|
|
run: |
|
|
cd sas
|
|
npm i
|
|
sasjs c -t sas9
|
|
rm -rf sasjsbuild/tests
|
|
sasjs b -t sas9
|
|
cp sasjsbuild/mysas9deploy.sas ./demostream_sas9.sas
|
|
# remove streamed component and rebuild SAS 9 services
|
|
rm -rf sasjsbuild/services/web9
|
|
rm sasjsbuild/services/clickme.sas
|
|
sasjs b -t sas9
|
|
cp sasjsbuild/mysas9deploy.sas ./sas9.sas
|
|
|
|
- name: Build SASjs Server Release
|
|
run: |
|
|
cd sas
|
|
cp sasjs/utils/favicon.ico ../client/dist/favicon.ico
|
|
sasjs c -t server
|
|
rm -rf sasjsbuild/tests
|
|
server_apploc="/Public/app/dc"
|
|
sed -i "s|apploc=\"[^\"]*\"|apploc=\"${server_apploc}\"|g" sasjsbuild/services/web/index.html
|
|
sasjs b -t server
|
|
cp sasjsbuild/server.json.zip ./sasjs_server.json.zip
|
|
|
|
- name: Build Viya Release
|
|
run: |
|
|
cd sas
|
|
sasjs c -t viya
|
|
rm -rf sasjsbuild/tests
|
|
sed -i -e 's/servertype="SASJS"/servertype="SASVIYA"/g' sasjsbuild/services/DC.html
|
|
sasjs b -t viya
|
|
cp sasjsbuild/viya.sas ./viya.sas
|
|
# compile Viya Full deploy (without web)
|
|
rm -rf sasjsbuild/services/web
|
|
rm sasjsbuild/services/DC.html
|
|
sasjs b -t viya
|
|
cp sasjsbuild/viya.sas ./viya_noweb.sas
|
|
cp sasjsbuild/viya.json ./viya_noweb.json
|
|
|
|
- name: Zip Frontend (including viya.json for full viya deploy)
|
|
run: |
|
|
cd sas
|
|
cp sasjsbuild/viya.json ../client/dist/viya.json
|
|
# Zip from *inside* dist so the archive holds the frontend files at its
|
|
# root rather than under a client/dist/ prefix (see #147).
|
|
cd ../client/dist
|
|
zip -r ../../frontend.zip .
|
|
|
|
- name: Upload assets to the release
|
|
env:
|
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
run: |
|
|
set -euo pipefail
|
|
AUTH_HEADER="Authorization: token $GITEA_TOKEN"
|
|
BASE="${{ gitea.server_url }}/api/v1/repos/${{ gitea.repository }}"
|
|
|
|
RELEASE_JSON=$(curl --fail-with-body -sS -H "$AUTH_HEADER" "$BASE/releases/tags/${TAG}")
|
|
RELEASE_ID=$(echo "$RELEASE_JSON" | jq -r '.id')
|
|
RELEASE_BODY=$(echo "$RELEASE_JSON" | jq -r '.body')
|
|
|
|
ASSETS=(frontend.zip
|
|
sas/demostream_sas9.sas
|
|
sas/viya.sas
|
|
sas/sasjs_server.json.zip
|
|
sas/sas9.sas
|
|
sas/viya_noweb.sas
|
|
sas/viya_noweb.json)
|
|
|
|
: > SHA256SUMS
|
|
for f in "${ASSETS[@]}"; do
|
|
sum=$(sha256sum "$f" | cut -d' ' -f1)
|
|
printf '%s %s\n' "$sum" "${f##*/}" >> SHA256SUMS
|
|
done
|
|
cat SHA256SUMS
|
|
|
|
# Replacing the assets means removing the ones this workflow uploads,
|
|
# and a second run must not append the verification section twice. An
|
|
# asset the release carries from another source is left alone.
|
|
OWNED=$(printf '%s\n' "${ASSETS[@]##*/}" SHA256SUMS)
|
|
echo "$RELEASE_JSON" | jq -r '.assets[]? | "\(.id) \(.name)"' |
|
|
while read -r asset_id asset_name; do
|
|
if printf '%s\n' "$OWNED" | grep -qxF -- "$asset_name"; then
|
|
echo "Removing previous ${asset_name}"
|
|
curl --fail-with-body -sS -X DELETE -H "$AUTH_HEADER" "$BASE/releases/${RELEASE_ID}/assets/${asset_id}"
|
|
else
|
|
echo "Leaving ${asset_name} in place: this workflow did not upload it"
|
|
fi
|
|
done
|
|
|
|
if echo "$RELEASE_BODY" | grep -q "## Verifying the download"; then
|
|
echo "Release body already carries the verification section"
|
|
else
|
|
VERIFY_SECTION=$(./.gitea/scripts/verify-section.sh)
|
|
NEW_BODY=$(jq -nr --arg body "$RELEASE_BODY" --arg verify "$VERIFY_SECTION" \
|
|
'$body + "\n" + $verify + "\n\nFor installation instructions, please visit https://docs.datacontroller.io/"')
|
|
curl --fail-with-body -sS -X PATCH \
|
|
-H "$AUTH_HEADER" \
|
|
-H 'Content-Type: application/json' \
|
|
--data "$(jq -n --arg body "$NEW_BODY" '{draft:false, body:$body}')" \
|
|
"$BASE/releases/$RELEASE_ID"
|
|
fi
|
|
|
|
URL="$BASE/releases/${RELEASE_ID}/assets"
|
|
for f in "${ASSETS[@]}"; do
|
|
echo "Uploading $f ..."
|
|
curl --fail-with-body -sS -H "$AUTH_HEADER" "$URL" -F "attachment=@$f"
|
|
done
|
|
echo "Uploading SHA256SUMS ..."
|
|
curl --fail-with-body -sS -H "$AUTH_HEADER" "$URL" -F "attachment=@SHA256SUMS"
|
|
|
|
- name: Remove registry config
|
|
# written earlier in this job; nothing deletes it on the way out
|
|
if: always()
|
|
run: rm -f "$RUNNER_TEMP/npmrc"
|