Update release_pipeline.yml

This commit is contained in:
Jonathan Miller
2026-01-01 09:10:08 -06:00
committed by GitHub
parent 00bf93df11
commit b6dcbf1c9c

View File

@@ -64,6 +64,8 @@ concurrency: group: release-pipeline-${{ github.ref_name }} cancel-in-progress:
defaults: run: shell: bash defaults: run: shell: bash
Principle of least privilege. Jobs elevate as needed.
permissions: contents: read permissions: contents: read
jobs: guard: name: 00 Guardrails and metadata runs-on: ubuntu-latest jobs: guard: name: 00 Guardrails and metadata runs-on: ubuntu-latest
@@ -81,8 +83,6 @@ outputs:
permissions: permissions:
contents: read contents: read
actions: read
pull-requests: read
steps: steps:
- name: Checkout (best effort) - name: Checkout (best effort)
@@ -99,20 +99,15 @@ steps:
const repo = context.repo.repo; const repo = context.repo.repo;
const username = context.actor; const username = context.actor;
const res = await github.rest.repos.getCollaboratorPermissionLevel({ const res = await github.rest.repos.getCollaboratorPermissionLevel({ owner, repo, username });
owner, const perm = (res && res.data && res.data.permission) ? String(res.data.permission).toLowerCase() : "unknown";
repo, const allowed = (perm === "admin" || perm === "maintain");
username,
});
const perm = (res?.data?.permission || '').toLowerCase(); core.setOutput("permission", perm);
const allowed = (perm === 'admin' || perm === 'maintain'); core.setOutput("allowed", allowed ? "true" : "false");
core.setOutput('permission', perm || 'unknown');
core.setOutput('allowed', allowed ? 'true' : 'false');
if (!allowed) { if (!allowed) {
core.setFailed(`Actor ${username} lacks required role (admin or maintain). Detected permission: ${perm || 'unknown'}.`); core.setFailed(`Actor ${username} lacks required role (admin or maintain). Detected permission: ${perm}.`);
} }
- name: Validate trigger and extract metadata - name: Validate trigger and extract metadata
@@ -205,28 +200,28 @@ steps:
{ {
echo "### Guard report" echo "### Guard report"
echo "```json" echo "```json"
echo "{" echo "{"
echo " \"repository\": \"${GITHUB_REPOSITORY}\"," echo " \"repository\": \"${GITHUB_REPOSITORY}\","
echo " \"workflow\": \"${GITHUB_WORKFLOW}\"," echo " \"workflow\": \"${GITHUB_WORKFLOW}\","
echo " \"job\": \"${GITHUB_JOB}\"," echo " \"job\": \"${GITHUB_JOB}\","
echo " \"run_id\": ${GITHUB_RUN_ID}," echo " \"run_id\": ${GITHUB_RUN_ID},"
echo " \"run_number\": ${GITHUB_RUN_NUMBER}," echo " \"run_number\": ${GITHUB_RUN_NUMBER},"
echo " \"run_attempt\": ${GITHUB_RUN_ATTEMPT}," echo " \"run_attempt\": ${GITHUB_RUN_ATTEMPT},"
echo " \"run_url\": \"${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\"," echo " \"run_url\": \"${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\","
echo " \"actor\": \"${GITHUB_ACTOR}\"," echo " \"actor\": \"${GITHUB_ACTOR}\","
echo " \"actor_permission\": \"${{ steps.auth.outputs.permission }}\"," echo " \"actor_permission\": \"${{ steps.auth.outputs.permission }}\","
echo " \"sha\": \"${GITHUB_SHA}\"," echo " \"sha\": \"${GITHUB_SHA}\","
echo " \"event\": \"${EVENT_NAME}\"," echo " \"event\": \"${EVENT_NAME}\","
echo " \"ref\": \"${REF_NAME}\"," echo " \"ref\": \"${REF_NAME}\","
echo " \"version\": \"${VERSION}\"," echo " \"version\": \"${VERSION}\","
echo " \"source_branch\": \"${SOURCE_BRANCH}\"," echo " \"source_branch\": \"${SOURCE_BRANCH}\","
echo " \"target_branch\": \"${TARGET_BRANCH}\"," echo " \"target_branch\": \"${TARGET_BRANCH}\","
echo " \"promoted_branch\": \"${PROMOTED_BRANCH}\"," echo " \"promoted_branch\": \"${PROMOTED_BRANCH}\","
echo " \"channel\": \"${CHANNEL}\"," echo " \"channel\": \"${CHANNEL}\","
echo " \"release_mode\": \"${RELEASE_MODE}\"," echo " \"release_mode\": \"${RELEASE_MODE}\","
echo " \"override\": \"${OVERRIDE}\"," echo " \"override\": \"${OVERRIDE}\","
echo " \"today_utc\": \"${TODAY_UTC}\"" echo " \"today_utc\": \"${TODAY_UTC}\""
echo "}" echo "}"
echo "```" echo "```"
} >> "${GITHUB_STEP_SUMMARY}" } >> "${GITHUB_STEP_SUMMARY}"
@@ -252,11 +247,11 @@ steps:
printf '"sha":"%s",' "${GITHUB_SHA}" printf '"sha":"%s",' "${GITHUB_SHA}"
printf '"runner_os":"%s",' "${RUNNER_OS}" printf '"runner_os":"%s",' "${RUNNER_OS}"
printf '"runner_name":"%s"' "${RUNNER_NAME}" printf '"runner_name":"%s"' "${RUNNER_NAME}"
printf '} printf '}\n'
echo "```"
} >> "${GITHUB_STEP_SUMMARY}"
' echo "```" } >> "${GITHUB_STEP_SUMMARY}" {
{
echo "### Git snapshot" echo "### Git snapshot"
echo "```" echo "```"
git --version || true git --version || true
@@ -333,23 +328,12 @@ steps:
run: | run: |
set -euo pipefail set -euo pipefail
{ {
echo "### Run context" echo "### Git snapshot"
echo "```json" echo "```"
printf '{' git status --porcelain=v1 || true
printf '"repository":"%s",' "${GITHUB_REPOSITORY}" git log -1 --pretty=fuller || true
printf '"workflow":"%s",' "${GITHUB_WORKFLOW}" echo "```"
printf '"job":"%s",' "${GITHUB_JOB}" } >> "${GITHUB_STEP_SUMMARY}"
printf '"run_id":%s,' "${GITHUB_RUN_ID}"
printf '"run_number":%s,' "${GITHUB_RUN_NUMBER}"
printf '"run_attempt":%s,' "${GITHUB_RUN_ATTEMPT}"
printf '"run_url":"%s",' "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
printf '"actor":"%s",' "${GITHUB_ACTOR}"
printf '"event":"%s",' "${GITHUB_EVENT_NAME}"
printf '"ref_name":"%s",' "${GITHUB_REF_NAME}"
printf '"sha":"%s"' "${GITHUB_SHA}"
printf '}
' echo "```" } >> "${GITHUB_STEP_SUMMARY}"
normalize_dates: name: 02 Normalize dates on promoted branch runs-on: ubuntu-latest needs: - guard - promote_branch normalize_dates: name: 02 Normalize dates on promoted branch runs-on: ubuntu-latest needs: - guard - promote_branch
@@ -418,11 +402,15 @@ steps:
{ {
echo "ERROR: Date normalization script not found in approved locations." echo "ERROR: Date normalization script not found in approved locations."
echo "Approved locations:" echo "Approved locations:"
printf '%s printf '%s\n' "${CANDIDATES[@]}"
echo "Discovered candidates (first 5):"
echo "${FOUND:-<none>}"
echo "Required action: add scripts/release/update_dates.sh (preferred) to the repo."
} >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
' "${CANDIDATES[@]}" echo "Discovered candidates (first 5):" echo "${FOUND:-<none>}" echo "Required action: add scripts/release/update_dates.sh (preferred) to the repo." } >> "${GITHUB_STEP_SUMMARY}" exit 1 fi echo "Using date script: ${SCRIPT}" >> "${GITHUB_STEP_SUMMARY}"
echo "Using date script: ${SCRIPT}" >> "${GITHUB_STEP_SUMMARY}"
chmod +x "${SCRIPT}" chmod +x "${SCRIPT}"
"${SCRIPT}" "${TODAY}" "${VERSION}" >> "${GITHUB_STEP_SUMMARY}" "${SCRIPT}" "${TODAY}" "${VERSION}" >> "${GITHUB_STEP_SUMMARY}"
@@ -534,14 +522,14 @@ steps:
printf '%s"%s"' "${sep}" "${m}" printf '%s"%s"' "${sep}" "${m}"
sep=","; sep=",";
done done
printf '],"channel":"%s","deploy_dry_run":"%s","credential_presence":{"FTP_KEY":"%s","FTP_PASSWORD":"%s"}} printf '],"channel":"%s","deploy_dry_run":"%s","credential_presence":{"FTP_KEY":"%s","FTP_PASSWORD":"%s"}}\n' \
"${CHANNEL}" "${DEPLOY_DRY_RUN:-false}" \
"$( [ "${key_present}" = "true" ] && echo present || echo missing )" \
"$( [ "${pw_present}" = "true" ] && echo present || echo missing )"
echo "```"
} >> "${GITHUB_STEP_SUMMARY}"
' if [ "${#missing[@]}" -gt 0 ]; then
"${CHANNEL}" "${DEPLOY_DRY_RUN:-false}"
"$( [ "${key_present}" = "true" ] && echo present || echo missing )"
"$( [ "${pw_present}" = "true" ] && echo present || echo missing )" echo "```" } >> "${GITHUB_STEP_SUMMARY}"
if [ "${#missing[@]}" -gt 0 ]; then
exit 1 exit 1
fi fi
@@ -582,11 +570,13 @@ if [ "${#missing[@]}" -gt 0 ]; then
printf '%s"%s"' "${sep}" "${m}" printf '%s"%s"' "${sep}" "${m}"
sep=","; sep=",";
done done
printf ']} printf ']}\n'
echo "```"
} >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
' echo "```" } >> "${GITHUB_STEP_SUMMARY}" exit 1 fi ran=()
ran=()
skipped=() skipped=()
for s in "${required_scripts[@]}" "${optional_scripts[@]}"; do for s in "${required_scripts[@]}" "${optional_scripts[@]}"; do
@@ -636,11 +626,11 @@ ran=()
sep=","; sep=",";
done done
printf ']} printf ']}\n'
echo "```"
} >> "${GITHUB_STEP_SUMMARY}"
' echo "```" } >> "${GITHUB_STEP_SUMMARY}" - name: Build Joomla ZIP (extension type aware, src-only archive)
- name: Build Joomla ZIP (extension type aware, src-only archive)
id: build id: build
run: | run: |
set -euo pipefail set -euo pipefail
@@ -691,7 +681,6 @@ ran=()
echo "zip_name=${ZIP}" >> "${GITHUB_OUTPUT}" echo "zip_name=${ZIP}" >> "${GITHUB_OUTPUT}"
echo "dist_dir=${DIST_DIR}" >> "${GITHUB_OUTPUT}" echo "dist_dir=${DIST_DIR}" >> "${GITHUB_OUTPUT}"
echo "root=src" >> "${GITHUB_OUTPUT}"
echo "manifest=${MANIFEST}" >> "${GITHUB_OUTPUT}" echo "manifest=${MANIFEST}" >> "${GITHUB_OUTPUT}"
echo "ext_type=${EXT_TYPE}" >> "${GITHUB_OUTPUT}" echo "ext_type=${EXT_TYPE}" >> "${GITHUB_OUTPUT}"
@@ -700,7 +689,7 @@ ran=()
{ {
echo "### Build report" echo "### Build report"
echo "```json" echo "```json"
echo "{\"repository\":\"${GITHUB_REPOSITORY}\",\"workflow\":\"${GITHUB_WORKFLOW}\",\"job\":\"${GITHUB_JOB}\",\"run_id\":${GITHUB_RUN_ID},\"run_number\":${GITHUB_RUN_NUMBER},\"run_attempt\":${GITHUB_RUN_ATTEMPT},\"run_url\":\"${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\",\"actor\":\"${GITHUB_ACTOR}\",\"sha\":\"${GITHUB_SHA}\",\"root\":\"src\",\"manifest\":\"${MANIFEST}\",\"extension_type\":\"${EXT_TYPE}\",\"zip\":\"${DIST_DIR}/${ZIP}\",\"zip_bytes\":${ZIP_BYTES},\"archive_policy\":\"src_only\"}" echo "{\"repository\":\"${GITHUB_REPOSITORY}\",\"workflow\":\"${GITHUB_WORKFLOW}\",\"job\":\"${GITHUB_JOB}\",\"run_id\":${GITHUB_RUN_ID},\"run_number\":${GITHUB_RUN_NUMBER},\"run_attempt\":${GITHUB_RUN_ATTEMPT},\"run_url\":\"${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}\",\"actor\":\"${GITHUB_ACTOR}\",\"sha\":\"${GITHUB_SHA}\",\"archive_policy\":\"src_only\",\"manifest\":\"${MANIFEST}\",\"extension_type\":\"${EXT_TYPE}\",\"zip\":\"${DIST_DIR}/${ZIP}\",\"zip_bytes\":${ZIP_BYTES}}"
echo "```" echo "```"
} >> "${GITHUB_STEP_SUMMARY}" } >> "${GITHUB_STEP_SUMMARY}"
@@ -721,7 +710,7 @@ ran=()
echo "```" echo "```"
} >> "${GITHUB_STEP_SUMMARY}" } >> "${GITHUB_STEP_SUMMARY}"
- name: Upload ZIP to SFTP (key-preferred, password-fallback, overwrite, verified, classified) - name: Upload ZIP to SFTP (key-preferred, password-fallback, overwrite, verified)
id: sftp id: sftp
env: env:
FTP_HOST: ${{ secrets.FTP_HOST }} FTP_HOST: ${{ secrets.FTP_HOST }}
@@ -764,24 +753,12 @@ ran=()
REMOTE_PATH="${FTP_PATH%/}/${CHANNEL}" REMOTE_PATH="${FTP_PATH%/}/${CHANNEL}"
fi fi
if [ -z "${REMOTE_PATH}" ] || [ "${REMOTE_PATH}" = "/" ]; then
echo "ERROR: Unsafe REMOTE_PATH resolved (${REMOTE_PATH:-<empty>})" >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
if printf '%s' "${REMOTE_PATH}" | awk -F/ '{print NF-1}' | grep -Eq '^[01]$'; then
echo "ERROR: Remote path lacks depth guardrail: ${REMOTE_PATH}" >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
AUTH_MODE="password" AUTH_MODE="password"
if [ -n "${FTP_KEY:-}" ]; then if [ -n "${FTP_KEY:-}" ]; then
AUTH_MODE="key" AUTH_MODE="key"
fi fi
PASSWORD_PRESENT="$( [ -n "${FTP_PASSWORD:-}" ] && echo true || echo false )" if [ "${AUTH_MODE}" = "password" ] && [ -z "${FTP_PASSWORD:-}" ]; then
KEY_PRESENT="$( [ -n "${FTP_KEY:-}" ] && echo true || echo false )"
if [ "${AUTH_MODE}" = "password" ] && [ "${PASSWORD_PRESENT}" != "true" ]; then
echo "ERROR: FTP_PASSWORD required when FTP_KEY is not provided" >> "${GITHUB_STEP_SUMMARY}" echo "ERROR: FTP_PASSWORD required when FTP_KEY is not provided" >> "${GITHUB_STEP_SUMMARY}"
exit 1 exit 1
fi fi
@@ -800,21 +777,11 @@ ran=()
printf '"host":"%s",' "${FTP_HOST}" printf '"host":"%s",' "${FTP_HOST}"
printf '"port":"%s",' "${PORT:-default}" printf '"port":"%s",' "${PORT:-default}"
printf '"remote_path":"%s",' "${REMOTE_PATH}" printf '"remote_path":"%s",' "${REMOTE_PATH}"
printf '"overwrite_policy":"same_filename_only",' printf '"overwrite":true,'
printf '"cleanup_policy":"disabled",' printf '"dry_run":%s' "${DRY_RUN}"
printf '"dry_run":%s,' "${DRY_RUN}" printf '}\n'
printf '"zip":"%s",' "${ZIP}" echo "```"
printf '"credential_presence":{' } >> "${GITHUB_STEP_SUMMARY}"
printf '"FTP_KEY":"%s",' "$( [ "${KEY_PRESENT}" = "true" ] && echo present || echo missing )"
printf '"FTP_PASSWORD":"%s"' "$( [ "${PASSWORD_PRESENT}" = "true" ] && echo present || echo missing )"
printf '}'
printf '}
' echo "```" } >> "${GITHUB_STEP_SUMMARY}"
if [ "${KEY_PRESENT}" = "true" ] && [ "${PASSWORD_PRESENT}" = "true" ]; then
echo "Password provided but ignored because key auth is in use." >> "${GITHUB_STEP_SUMMARY}"
fi
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install -y lftp openssh-client putty-tools sudo apt-get install -y lftp openssh-client putty-tools
@@ -830,11 +797,7 @@ if [ "${KEY_PRESENT}" = "true" ] && [ "${PASSWORD_PRESENT}" = "true" ]; then
if grep -Eq '^Encryption: *none[[:space:]]*$' ~/.ssh/key.ppk; then if grep -Eq '^Encryption: *none[[:space:]]*$' ~/.ssh/key.ppk; then
PPK_PASSPHRASE="" PPK_PASSPHRASE=""
else else
if [ -z "${FTP_PASSWORD:-}" ]; then PPK_PASSPHRASE="${FTP_PASSWORD:-}"
echo "ERROR: Encrypted PPK detected but FTP_PASSWORD not provided" >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
PPK_PASSPHRASE="${FTP_PASSWORD}"
fi fi
if [ -n "${PPK_PASSPHRASE}" ]; then if [ -n "${PPK_PASSPHRASE}" ]; then
@@ -861,46 +824,8 @@ if [ "${KEY_PRESENT}" = "true" ] && [ "${PASSWORD_PRESENT}" = "true" ]; then
OPEN="open -u '${FTP_USER}','${FTP_PASSWORD}', sftp://${HOSTPORT}" OPEN="open -u '${FTP_USER}','${FTP_PASSWORD}', sftp://${HOSTPORT}"
fi fi
ZIP_BYTES_LOCAL="$(stat -c%s "${DIST_DIR}/${ZIP}")"
set +e
preflight_log="$(mktemp)"
lftp -d -e "\
set sftp:auto-confirm yes; \
set cmd:trace yes; \
set net:timeout 30; \
set net:max-retries 3; \
set net:reconnect-interval-base 5; \
${CONNECT}; \
${OPEN}; \
mkdir -p '${REMOTE_PATH}'; \
cd '${REMOTE_PATH}'; \
ls -la; \
bye" >"${preflight_log}" 2>&1
preflight_rc=$?
set -e
if [ "${preflight_rc}" -ne 0 ]; then
{
echo "### SFTP preflight log"
echo "```"
tail -n 400 "${preflight_log}" || true
echo "```"
} >> "${GITHUB_STEP_SUMMARY}" || true
exit "${preflight_rc}"
fi
if grep -F " ${ZIP}" "${preflight_log}" >/dev/null 2>&1; then
echo "Remote file already exists and will be overwritten (same filename policy): ${ZIP}" >> "${GITHUB_STEP_SUMMARY}"
else
echo "Remote file not present, proceeding with first publish: ${ZIP}" >> "${GITHUB_STEP_SUMMARY}"
fi
if [ "${DRY_RUN}" = "true" ]; then if [ "${DRY_RUN}" = "true" ]; then
{ echo "Dry run enabled. Upload skipped." >> "${GITHUB_STEP_SUMMARY}"
echo "### Dry run"
echo "Dry run enabled. Upload skipped."
} >> "${GITHUB_STEP_SUMMARY}"
echo "auth_mode=${AUTH_MODE}" >> "${GITHUB_OUTPUT}" echo "auth_mode=${AUTH_MODE}" >> "${GITHUB_OUTPUT}"
echo "remote_path=${REMOTE_PATH}" >> "${GITHUB_OUTPUT}" echo "remote_path=${REMOTE_PATH}" >> "${GITHUB_OUTPUT}"
echo "host=${FTP_HOST}" >> "${GITHUB_OUTPUT}" echo "host=${FTP_HOST}" >> "${GITHUB_OUTPUT}"
@@ -918,6 +843,7 @@ if [ "${KEY_PRESENT}" = "true" ] && [ "${PASSWORD_PRESENT}" = "true" ]; then
set net:reconnect-interval-base 5; \ set net:reconnect-interval-base 5; \
${CONNECT}; \ ${CONNECT}; \
${OPEN}; \ ${OPEN}; \
mkdir -p '${REMOTE_PATH}'; \
cd '${REMOTE_PATH}'; \ cd '${REMOTE_PATH}'; \
put -E '${DIST_DIR}/${ZIP}'; \ put -E '${DIST_DIR}/${ZIP}'; \
ls -l; \ ls -l; \
@@ -925,55 +851,21 @@ if [ "${KEY_PRESENT}" = "true" ] && [ "${PASSWORD_PRESENT}" = "true" ]; then
rc=$? rc=$?
set -e set -e
failure_class="none"
if [ "${rc}" -ne 0 ]; then
if grep -Ei 'auth|authentication|login failed' "${upload_log}" >/dev/null 2>&1; then
failure_class="auth_failure"
elif grep -Ei 'name or service not known|temporary failure in name resolution|no such host' "${upload_log}" >/dev/null 2>&1; then
failure_class="dns_failure"
elif grep -Ei 'connection timed out|timeout' "${upload_log}" >/dev/null 2>&1; then
failure_class="timeout"
elif grep -Ei 'no route to host|network is unreachable|connection refused' "${upload_log}" >/dev/null 2>&1; then
failure_class="network_failure"
elif grep -Ei 'permission denied' "${upload_log}" >/dev/null 2>&1; then
failure_class="permission_denied"
else
failure_class="unknown"
fi
fi
{
echo "### SFTP session log"
echo "```"
tail -n 400 "${upload_log}" || true
echo "```"
} >> "${GITHUB_STEP_SUMMARY}" || true
if [ "${rc}" -ne 0 ]; then if [ "${rc}" -ne 0 ]; then
{ {
echo "### SFTP failure classification" echo "### SFTP session log"
echo "```json"
echo "{\"status\":\"fail\",\"class\":\"${failure_class}\",\"exit_code\":${rc}}"
echo "```" echo "```"
} >> "${GITHUB_STEP_SUMMARY}" tail -n 400 "${upload_log}" || true
echo "```"
} >> "${GITHUB_STEP_SUMMARY}" || true
exit "${rc}" exit "${rc}"
fi fi
if ! grep -F " ${ZIP}" "${upload_log}" >/dev/null 2>&1; then ZIP_BYTES_LOCAL="$(stat -c%s "${DIST_DIR}/${ZIP}")"
echo "ERROR: Upload completed but verification failed. ZIP not visible in remote listing." >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
ZIP_BYTES_REMOTE="unknown"
ZIP_BYTES_REMOTE="$(awk -v z="${ZIP}" '$NF==z {print $(NF-4)}' "${upload_log}" | tail -n 1 || true)"
if [ -z "${ZIP_BYTES_REMOTE}" ]; then
ZIP_BYTES_REMOTE="unknown"
fi
{ {
echo "### SFTP upload report" echo "### SFTP upload report"
echo "```json" echo "```json"
echo "{\"status\":\"ok\",\"protocol\":\"sftp\",\"auth_mode\":\"${AUTH_MODE}\",\"host\":\"${FTP_HOST}\",\"port\":\"${PORT:-default}\",\"remote_path\":\"${REMOTE_PATH}\",\"zip\":\"${ZIP}\",\"zip_bytes_local\":${ZIP_BYTES_LOCAL},\"zip_bytes_remote\":\"${ZIP_BYTES_REMOTE}\",\"overwrite\":true,\"cleanup_policy\":\"disabled\"}" echo "{\"status\":\"ok\",\"protocol\":\"sftp\",\"auth_mode\":\"${AUTH_MODE}\",\"host\":\"${FTP_HOST}\",\"port\":\"${PORT:-default}\",\"remote_path\":\"${REMOTE_PATH}\",\"zip\":\"${ZIP}\",\"zip_bytes_local\":${ZIP_BYTES_LOCAL},\"overwrite\":true}"
echo "```" echo "```"
} >> "${GITHUB_STEP_SUMMARY}" } >> "${GITHUB_STEP_SUMMARY}"
@@ -1007,6 +899,11 @@ if [ "${KEY_PRESENT}" = "true" ] && [ "${PASSWORD_PRESENT}" = "true" ]; then
echo "tag=${TAG}" >> "${GITHUB_OUTPUT}" echo "tag=${TAG}" >> "${GITHUB_OUTPUT}"
- name: Generate release notes from CHANGELOG.md - name: Generate release notes from CHANGELOG.md
env:
SFTP_AUTH_MODE: ${{ steps.sftp.outputs.auth_mode }}
SFTP_REMOTE_PATH: ${{ steps.sftp.outputs.remote_path }}
SFTP_HOST: ${{ steps.sftp.outputs.host }}
SFTP_PORT: ${{ steps.sftp.outputs.port }}
run: | run: |
set -euo pipefail set -euo pipefail
@@ -1026,10 +923,10 @@ if [ "${KEY_PRESENT}" = "true" ] && [ "${PASSWORD_PRESENT}" = "true" ]; then
echo "- ${ZIP_ASSET}" echo "- ${ZIP_ASSET}"
echo "" echo ""
echo "Deployment metadata:" echo "Deployment metadata:"
echo "- auth_mode: ${{ steps.sftp.outputs.auth_mode || 'unknown' }}" echo "- auth_mode: ${SFTP_AUTH_MODE:-unknown}"
echo "- remote_path: ${{ steps.sftp.outputs.remote_path || 'unknown' }}" echo "- remote_path: ${SFTP_REMOTE_PATH:-unknown}"
echo "- host: ${{ steps.sftp.outputs.host || 'unknown' }}" echo "- host: ${SFTP_HOST:-unknown}"
echo "- port: ${{ steps.sftp.outputs.port || 'unknown' }}" echo "- port: ${SFTP_PORT:-unknown}"
} >> RELEASE_NOTES.md } >> RELEASE_NOTES.md
- name: Create GitHub release and attach ZIP - name: Create GitHub release and attach ZIP
@@ -1143,19 +1040,18 @@ steps:
- name: Release event telemetry - name: Release event telemetry
run: | run: |
set -euo pipefail set -euo pipefail
{ {
echo "### Release event telemetry" echo "### Release event telemetry"
echo "```json" echo "```json"
echo "{" echo "{"
echo " \"repository\": \"${GITHUB_REPOSITORY}\"," echo " \"repository\": \"${GITHUB_REPOSITORY}\","
echo " \"event\": \"${GITHUB_EVENT_NAME}\"," echo " \"event\": \"${GITHUB_EVENT_NAME}\","
echo " \"ref_name\": \"${GITHUB_REF_NAME}\"," echo " \"ref_name\": \"${GITHUB_REF_NAME}\","
echo " \"sha\": \"${GITHUB_SHA}\"," echo " \"sha\": \"${GITHUB_SHA}\","
echo " \"channel\": \"${{ needs.guard.outputs.channel }}\"," echo " \"channel\": \"${{ needs.guard.outputs.channel }}\","
echo " \"release_mode\": \"${{ needs.guard.outputs.release_mode }}\"," echo " \"release_mode\": \"${{ needs.guard.outputs.release_mode }}\","
echo " \"version\": \"${{ needs.guard.outputs.version }}\"" echo " \"version\": \"${{ needs.guard.outputs.version }}\""
echo "}" echo "}"
echo "```" echo "```"
} >> "${GITHUB_STEP_SUMMARY}" } >> "${GITHUB_STEP_SUMMARY}"