mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-06 03:59:14 +00:00
28f677d723
The upgrade report only ever showed the requested deb URLs and a case table. The nightly chain runs died installing the OLD package (default from_version 1.0.0-rc.4-preview.1 has no .deb asset on its release, and release 1.0.0-rc.4 ships none either), leaving an empty Total: 0 report with no indication of what was upgraded. - Default from_version is now 1.0.0-rc.3 (ships rustfs_1.0.0.rc.3_amd64.deb). Matches the auto-testing default from PR #32. - The report generator also parses the [UPG-TOPO] lines the suite now emits and renders an 'Upgrade Matrix' section: per topology and KMS backend, the versions actually in place before/after (captured via 'rustfs --version' on the node) and the aggregated result. When the suite dies before any topology completes, the matrix says so instead of silently showing nothing.
468 lines
20 KiB
YAML
468 lines
20 KiB
YAML
# Copyright 2024 RustFS Team
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
name: RustFS Upgrade Test
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
from_version:
|
|
description: 'OLD RustFS release tag (must ship a .deb asset, e.g. 1.0.0-rc.3)'
|
|
required: false
|
|
default: '1.0.0-rc.3'
|
|
from_url:
|
|
description: 'OLD .deb URL. Overrides from_version.'
|
|
required: false
|
|
type: string
|
|
to_version:
|
|
description: 'NEW RustFS release tag (leave empty for latest nightly)'
|
|
required: false
|
|
to_url:
|
|
description: 'NEW .deb URL. Overrides to_version / nightly default.'
|
|
required: false
|
|
type: string
|
|
topology:
|
|
description: 'Topology to run (all = SNSD, SNMD, MNMD)'
|
|
type: choice
|
|
options:
|
|
- all
|
|
- single-single
|
|
- single-multi
|
|
- multi-multi
|
|
default: all
|
|
backends:
|
|
description: 'KMS backends to run (local,vault-kv2)'
|
|
required: false
|
|
default: 'local,vault-kv2'
|
|
cleanup_before:
|
|
description: 'Reset the nodes before the test (DESTROYS existing data/config)'
|
|
type: boolean
|
|
default: true
|
|
cleanup_after:
|
|
description: 'Reset the nodes after the test (DESTROYS test data/config)'
|
|
type: boolean
|
|
default: true
|
|
repository_dispatch:
|
|
# Functional-chain entry: dispatched by rustfs-functional-chain.yml.
|
|
types: [rustfs-chain-upgrade]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: rustfs-shared-functional-tests
|
|
cancel-in-progress: false
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
env:
|
|
RUSTFS_ACCESS_KEY: ${{ secrets.RUSTFS_ACCESS_KEY }}
|
|
RUSTFS_SECRET_KEY: ${{ secrets.RUSTFS_SECRET_KEY }}
|
|
RUSTFS_NODES: ${{ secrets.RUSTFS_NODES || vars.RUSTFS_NODES }}
|
|
RUSTFS_SSH_USER: ${{ secrets.RUSTFS_SSH_USER || vars.RUSTFS_SSH_USER }}
|
|
RUSTFS_NIGHTLY_PACKAGE_URL: ${{ vars.RUSTFS_NIGHTLY_PACKAGE_URL || 'https://dl.rustfs.com/artifacts/rustfs/packages/nightly/rustfs-nightly-latest.deb' }}
|
|
PF_TESTING_GH_TOKEN: ${{ secrets.PF_TESTING_GH_TOKEN }}
|
|
|
|
jobs:
|
|
upgrade-test:
|
|
runs-on: smoke-testing
|
|
continue-on-error: true
|
|
timeout-minutes: 420
|
|
if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch' }}
|
|
steps:
|
|
# auto-testing is private: clone it with the dedicated PF token (not
|
|
# GITHUB_TOKEN) and retry transient GitHub/network failures.
|
|
- name: Checkout auto-testing scripts (with retry)
|
|
env:
|
|
GH_TOKEN: ${{ secrets.PF_TESTING_GH_TOKEN }}
|
|
run: |
|
|
set -euo pipefail
|
|
rm -rf auto-testing
|
|
for attempt in 1 2 3 4 5; do
|
|
if gh repo clone rustfs/auto-testing auto-testing -- --depth 1 --quiet; then
|
|
echo "auto-testing cloned (attempt ${attempt})"
|
|
exit 0
|
|
fi
|
|
rm -rf auto-testing
|
|
echo "clone attempt ${attempt} failed; retrying in $((attempt * 15))s" >&2
|
|
sleep $((attempt * 15))
|
|
done
|
|
echo "ERROR: unable to clone rustfs/auto-testing after 5 attempts" >&2
|
|
exit 1
|
|
|
|
- name: Show environment
|
|
run: |
|
|
uname -a
|
|
jq --version
|
|
openssl version
|
|
aws --version || true
|
|
docker --version || true
|
|
df -h /data | tail -1
|
|
|
|
- name: Cleanup environment (before)
|
|
if: ${{ inputs.cleanup_before != 'false' || github.event_name != 'workflow_dispatch' }}
|
|
run: |
|
|
set -euo pipefail
|
|
read -r -a NODES <<< "${RUSTFS_NODES:-vm000 vm001 vm002}"
|
|
SSH_USER="${RUSTFS_SSH_USER:-azureuser}"
|
|
for node in "${NODES[@]}"; do
|
|
ssh -o BatchMode=yes -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new "${SSH_USER}@${node}" '
|
|
set -euo pipefail
|
|
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo -n"
|
|
${SUDO} systemctl stop rustfs 2>/dev/null || true
|
|
if ${SUDO} dpkg -l rustfs 2>/dev/null | grep -q "^ii"; then
|
|
${SUDO} dpkg -P rustfs
|
|
fi
|
|
for i in 1 2 3 4; do ${SUDO} rm -rf /data/rustfs${i}/mnmd; done
|
|
${SUDO} rm -rf /var/log/rustfs /var/lib/rustfs/kms /var/lib/rustfs/kms-backup
|
|
'
|
|
done
|
|
|
|
- name: Ensure docker (Vault container)
|
|
run: |
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
sudo apt-get update
|
|
sudo apt-get install -y docker.io
|
|
fi
|
|
sudo systemctl enable --now docker
|
|
docker info >/dev/null 2>&1 || sudo docker info >/dev/null 2>&1
|
|
|
|
- name: Run upgrade compatibility suite
|
|
id: test
|
|
continue-on-error: true
|
|
env:
|
|
LOG_FILE: /tmp/rustfs-upgrade.log
|
|
run: |
|
|
set -euo pipefail
|
|
chmod +x auto-testing/rustfs-upgrade-test.sh
|
|
FROM_URL='${{ inputs.from_url }}'
|
|
FROM_VERSION='${{ inputs.from_version }}'
|
|
TO_URL='${{ inputs.to_url }}'
|
|
TO_VERSION='${{ inputs.to_version }}'
|
|
TOPOLOGY='${{ inputs.topology }}'
|
|
BACKENDS='${{ inputs.backends }}'
|
|
ARGS=(-y --log-file "${LOG_FILE}")
|
|
if [ "${TOPOLOGY}" = "all" ] || [ -z "${TOPOLOGY}" ] || [ "${TOPOLOGY}" = "null" ]; then
|
|
ARGS+=(--all-topologies)
|
|
else
|
|
ARGS+=(--topology "${TOPOLOGY}")
|
|
fi
|
|
if [ -n "${BACKENDS}" ] && [ "${BACKENDS}" != "null" ]; then
|
|
ARGS+=(--backends "${BACKENDS}")
|
|
fi
|
|
if [ -n "${FROM_URL}" ]; then
|
|
ARGS+=(--from-url "${FROM_URL}")
|
|
elif [ -n "${FROM_VERSION}" ] && [ "${FROM_VERSION}" != "null" ]; then
|
|
ARGS+=(--from-version "${FROM_VERSION}")
|
|
fi
|
|
if [ -n "${TO_URL}" ]; then
|
|
ARGS+=(--to-url "${TO_URL}")
|
|
elif [ -n "${TO_VERSION}" ] && [ "${TO_VERSION}" != "null" ]; then
|
|
ARGS+=(--to-version "${TO_VERSION}")
|
|
else
|
|
ARGS+=(--to-url "${RUSTFS_NIGHTLY_PACKAGE_URL}")
|
|
fi
|
|
./auto-testing/rustfs-upgrade-test.sh "${ARGS[@]}"
|
|
|
|
- name: Generate report
|
|
if: always()
|
|
env:
|
|
LOG_FILE: /tmp/rustfs-upgrade.log
|
|
REPORT_FILE: /tmp/rustfs-upgrade-report.md
|
|
run: |
|
|
set -euo pipefail
|
|
FROM_URL='${{ inputs.from_url }}'
|
|
FROM_VERSION='${{ inputs.from_version }}'
|
|
TO_URL='${{ inputs.to_url }}'
|
|
TO_VERSION='${{ inputs.to_version }}'
|
|
if [ -n "${FROM_URL}" ]; then
|
|
FROM_SOURCE="${FROM_URL}"
|
|
elif [ -n "${FROM_VERSION}" ]; then
|
|
FROM_SOURCE="version ${FROM_VERSION}"
|
|
else
|
|
FROM_SOURCE="release (default)"
|
|
fi
|
|
if [ -n "${TO_URL}" ]; then
|
|
TO_SOURCE="${TO_URL}"
|
|
elif [ -n "${TO_VERSION}" ]; then
|
|
TO_SOURCE="version ${TO_VERSION}"
|
|
else
|
|
TO_SOURCE="${RUSTFS_NIGHTLY_PACKAGE_URL}"
|
|
fi
|
|
CASE_TABLE="/tmp/rustfs-upgrade-cases.md"
|
|
MATRIX_TABLE="/tmp/rustfs-upgrade-matrix.md"
|
|
python3 - "${LOG_FILE}" "${CASE_TABLE}" "${MATRIX_TABLE}" <<'PY'
|
|
import re
|
|
import sys
|
|
|
|
log_file, out_file, matrix_file = sys.argv[1], sys.argv[2], sys.argv[3]
|
|
ansi = re.compile(r'\x1b\[[0-9;]*m')
|
|
start_re = re.compile(r'^---\s+([A-Z]+-[0-9]+)\s+(.+?)\s+---$')
|
|
done_re = re.compile(r'^\[(PASS|FAIL|UNSUPPORTED)\]\s+([A-Z]+-[0-9]+)\b')
|
|
topo_re = re.compile(
|
|
r'^\[UPG-TOPO\]\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+PASS=(\d+)\s+FAIL=(\d+)\s*$')
|
|
|
|
rows = []
|
|
index = {}
|
|
topo_rows = []
|
|
try:
|
|
with open(log_file, 'r', encoding='utf-8', errors='replace') as fh:
|
|
for raw in fh:
|
|
line = ansi.sub('', raw).strip()
|
|
m = topo_re.match(line)
|
|
if m:
|
|
topo_rows.append(m.groups())
|
|
continue
|
|
m = start_re.match(line)
|
|
if m:
|
|
case_id, name = m.group(1), m.group(2)
|
|
if case_id not in index:
|
|
index[case_id] = len(rows)
|
|
rows.append([case_id, name, 'RUNNING'])
|
|
continue
|
|
m = done_re.match(line)
|
|
if m:
|
|
status, case_id = m.group(1), m.group(2)
|
|
if case_id in index:
|
|
rows[index[case_id]][2] = status
|
|
else:
|
|
rows.append([case_id, case_id, status])
|
|
index[case_id] = len(rows) - 1
|
|
except FileNotFoundError:
|
|
rows = []
|
|
|
|
counts = {'PASS': 0, 'FAIL': 0, 'UNSUPPORTED': 0, 'RUNNING': 0}
|
|
for _, _, status in rows:
|
|
counts[status] = counts.get(status, 0) + 1
|
|
|
|
with open(out_file, 'w', encoding='utf-8') as out:
|
|
out.write('## Case Summary\n\n')
|
|
out.write(f"- Total: {len(rows)}\\n")
|
|
out.write(f"- PASS: {counts.get('PASS', 0)}\\n")
|
|
out.write(f"- FAIL: {counts.get('FAIL', 0)}\\n")
|
|
out.write(f"- UNSUPPORTED: {counts.get('UNSUPPORTED', 0)}\\n")
|
|
out.write('\\n')
|
|
out.write('| Case | Name | Status |\\n')
|
|
out.write('| --- | --- | --- |\\n')
|
|
for case_id, name, status in rows:
|
|
out.write(f'| {case_id} | {name} | {status} |\\n')
|
|
|
|
# Upgrade matrix: one row per topology/backend with the versions
|
|
# captured on the nodes (rustfs --version) and the aggregated
|
|
# result. The dashboard renders this table directly.
|
|
with open(matrix_file, 'w', encoding='utf-8') as out:
|
|
out.write('## Upgrade Matrix\n\n')
|
|
out.write('| Topology | KMS Backend | 升级前版本 | 升级后版本 | 升级结果 |\n')
|
|
out.write('| --- | --- | --- | --- | --- |\n')
|
|
for topo, backend, old_v, new_v, npass, nfail in topo_rows:
|
|
result = 'PASS' if nfail == '0' else 'FAIL'
|
|
out.write(f'| {topo} | {backend} | {old_v} | {new_v} | {result} (PASS={npass} FAIL={nfail}) |\n')
|
|
if not topo_rows:
|
|
out.write('| - | - | - | - | 未执行(套件在升级前失败) |\n')
|
|
PY
|
|
{
|
|
echo "# RustFS upgrade compatibility report"
|
|
echo ""
|
|
echo "- Run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
|
|
echo "- Trigger: ${{ github.event_name }}"
|
|
echo "- From: ${FROM_SOURCE}"
|
|
echo "- To: ${TO_SOURCE}"
|
|
echo "- Test Step Outcome: ${{ steps.test.outcome }}"
|
|
echo ""
|
|
cat "${MATRIX_TABLE}" || true
|
|
echo ""
|
|
cat "${CASE_TABLE}" || true
|
|
echo ""
|
|
echo "## Log tail"
|
|
echo '```text'
|
|
tail -n 200 "${LOG_FILE}" || true
|
|
echo '```'
|
|
} | tee "${REPORT_FILE}"
|
|
cat "${REPORT_FILE}" >> "${GITHUB_STEP_SUMMARY}"
|
|
|
|
- name: Upload functional report to dashboard
|
|
if: always()
|
|
continue-on-error: true
|
|
env:
|
|
GH_TOKEN: ${{ env.PF_TESTING_GH_TOKEN }}
|
|
REPORT_FILE: /tmp/rustfs-upgrade-report.md
|
|
SUITE: upgrade
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -z "${GH_TOKEN:-}" ]; then
|
|
echo "PF_TESTING_GH_TOKEN is not configured; skipping dashboard upload"
|
|
exit 0
|
|
fi
|
|
DATE="$(date -u +%Y-%m-%d)"
|
|
REPORT_PATH="functional-reports/${SUITE}/${DATE}.md"
|
|
CONTENT="$(python3 -c 'import base64,sys;print(base64.b64encode(open(sys.argv[1],"rb").read()).decode())' "${REPORT_FILE}")"
|
|
SHA="$(gh api "repos/rustfs/dashboard/contents/${REPORT_PATH}" -q '.sha' 2>/dev/null || true)"
|
|
if [ -n "${SHA}" ]; then
|
|
jq -n --arg msg "report(${SUITE}): ${DATE}" --arg content "${CONTENT}" --arg sha "${SHA}" \
|
|
'{message:$msg, content:$content, sha:$sha}' \
|
|
| gh api --method PUT "repos/rustfs/dashboard/contents/${REPORT_PATH}" --input - >/dev/null
|
|
else
|
|
jq -n --arg msg "report(${SUITE}): ${DATE}" --arg content "${CONTENT}" \
|
|
'{message:$msg, content:$content}' \
|
|
| gh api --method PUT "repos/rustfs/dashboard/contents/${REPORT_PATH}" --input - >/dev/null
|
|
fi
|
|
|
|
- name: File failure issue in rustfs/backlog
|
|
if: ${{ always() && (failure() || steps.test.outcome == 'failure' || steps.test.outcome == 'cancelled') }}
|
|
continue-on-error: true
|
|
env:
|
|
GH_TOKEN: ${{ secrets.PF_TESTING_GH_TOKEN }}
|
|
SUITE: 'upgrade'
|
|
SUITE_LABEL: 'Upgrade compatibility'
|
|
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
REPORT_FILE: '/tmp/rustfs-upgrade-report.md'
|
|
LOG_FILE: '/tmp/rustfs-upgrade.log'
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -z "${GH_TOKEN:-}" ]; then
|
|
echo "PF_TESTING_GH_TOKEN is not configured; skipping backlog issue"
|
|
exit 0
|
|
fi
|
|
TITLE="[functional][${SUITE}] ${SUITE_LABEL} suite failed (run ${GITHUB_RUN_ID})"
|
|
EXISTING="$(gh issue list -R rustfs/backlog --state all \
|
|
--search "in:title \"run ${GITHUB_RUN_ID}\"" \
|
|
--json number --jq '.[].number' || true)"
|
|
if [ -n "${EXISTING}" ]; then
|
|
echo "backlog issue already exists for run ${GITHUB_RUN_ID}; skipping"
|
|
exit 0
|
|
fi
|
|
redact() {
|
|
sed -E \
|
|
-e 's/(RUSTFS_(ACCESS_KEY|SECRET_KEY)[=: ]+)[^[:space:]]+/\1[REDACTED]/Ig' \
|
|
-e 's/(Authorization:).*/\1 [REDACTED]/Ig' \
|
|
-e 's/(X-Amz-Signature=)[^&[:space:]]+/\1[REDACTED]/Ig' \
|
|
-e 's/^.*(password|secret|token)[=: ].*/[REDACTED SENSITIVE LINE]/Ig'
|
|
}
|
|
BODY_FILE="$(mktemp)"
|
|
{
|
|
echo "The **${SUITE_LABEL}** functional suite failed."
|
|
echo ""
|
|
echo "- Suite: \`${SUITE}\`"
|
|
echo "- Run: ${RUN_URL}"
|
|
echo "- Trigger: ${GITHUB_EVENT_NAME}"
|
|
echo "- Date: $(date -u +%Y-%m-%d)"
|
|
echo ""
|
|
echo "## Report (errors and symptoms)"
|
|
echo ""
|
|
if [ -s "${REPORT_FILE}" ]; then
|
|
redact < "${REPORT_FILE}"
|
|
elif [ -s "${LOG_FILE:-}" ]; then
|
|
echo "(report file missing; log tail below)"
|
|
echo ""
|
|
tail -n 200 "${LOG_FILE}" | redact
|
|
else
|
|
echo "(no report or log file was produced)"
|
|
fi
|
|
} | head -c 55000 > "${BODY_FILE}"
|
|
gh label create functional-test -R rustfs/backlog --color d73a4a 2>/dev/null || true
|
|
if ! gh issue create -R rustfs/backlog --title "${TITLE}" \
|
|
--body-file "${BODY_FILE}" --label functional-test; then
|
|
gh issue create -R rustfs/backlog --title "${TITLE}" --body-file "${BODY_FILE}"
|
|
fi
|
|
echo "filed backlog issue for suite ${SUITE}"
|
|
|
|
- name: Upload report and logs
|
|
if: always()
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: rustfs-upgrade-test-${{ github.run_id }}
|
|
path: |
|
|
/tmp/rustfs-upgrade-report.md
|
|
/tmp/rustfs-upgrade.*/*
|
|
if-no-files-found: ignore
|
|
retention-days: 3
|
|
|
|
- name: Cleanup environment (after)
|
|
if: ${{ always() && (inputs.cleanup_after != 'false' || github.event_name != 'workflow_dispatch') }}
|
|
run: |
|
|
set -euo pipefail
|
|
read -r -a NODES <<< "${RUSTFS_NODES:-vm000 vm001 vm002}"
|
|
SSH_USER="${RUSTFS_SSH_USER:-azureuser}"
|
|
for node in "${NODES[@]}"; do
|
|
ssh -o BatchMode=yes -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new "${SSH_USER}@${node}" '
|
|
set -euo pipefail
|
|
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo -n"
|
|
${SUDO} systemctl stop rustfs 2>/dev/null || true
|
|
if ${SUDO} dpkg -l rustfs 2>/dev/null | grep -q "^ii"; then
|
|
${SUDO} dpkg -P rustfs
|
|
fi
|
|
for i in 1 2 3 4; do ${SUDO} rm -rf /data/rustfs${i}/mnmd; done
|
|
${SUDO} rm -rf /var/log/rustfs /var/lib/rustfs/kms /var/lib/rustfs/kms-backup
|
|
'
|
|
done
|
|
|
|
- name: "Continue functional chain (next: S3 compatibility)"
|
|
# Only chain-triggered runs forward to the next suite; standalone
|
|
# workflow_dispatch runs stop after their own cleanup. A failed
|
|
# handoff must never pass silently: it retries, then files an alert
|
|
# issue in rustfs/backlog so a stalled chain is visible.
|
|
if: ${{ always() && github.event_name == 'repository_dispatch' }}
|
|
continue-on-error: true
|
|
env:
|
|
GH_TOKEN: ${{ secrets.PF_TESTING_GH_TOKEN }}
|
|
run: |
|
|
set -uo pipefail
|
|
if [ -z "${GH_TOKEN:-}" ]; then
|
|
echo "PF_TESTING_GH_TOKEN is not configured; cannot dispatch the next suite" >&2
|
|
exit 1
|
|
fi
|
|
DISPATCHED=0
|
|
for attempt in 1 2 3; do
|
|
if gh api --method POST repos/rustfs/rustfs/dispatches \
|
|
-f event_type='rustfs-chain-s3' \
|
|
-F 'client_payload[from_suite]=upgrade'; then
|
|
echo "dispatched next suite S3 compatibility (attempt ${attempt})"
|
|
DISPATCHED=1
|
|
break
|
|
fi
|
|
echo "dispatch attempt ${attempt} failed; retrying in ${attempt}0s" >&2
|
|
sleep "${attempt}0"
|
|
done
|
|
if [ "${DISPATCHED:-0}" -ne 1 ]; then
|
|
echo "ERROR: functional chain stalled: could not dispatch S3 compatibility after 3 attempts" >&2
|
|
TITLE="[functional][chain] stalled after upgrade (run ${GITHUB_RUN_ID})"
|
|
BODY_FILE="$(mktemp)"
|
|
{
|
|
echo "The functional chain could not hand off from **upgrade** to **S3 compatibility** after 3 attempts."
|
|
echo ""
|
|
echo "- Failed suite job: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
|
|
echo "- Expected next event: 'rustfs-chain-s3'"
|
|
echo "- Likely cause: PF_TESTING_GH_TOKEN lacks contents:write on rustfs/rustfs, or the GitHub API was unavailable."
|
|
echo "- Recovery: re-dispatch manually with"
|
|
FENCE="$(printf "\x60\x60\x60")"; echo " ${FENCE}"
|
|
echo " gh api --method POST repos/rustfs/rustfs/dispatches -f event_type='rustfs-chain-s3'"
|
|
FENCE="$(printf "\x60\x60\x60")"; echo " ${FENCE}"
|
|
} > "${BODY_FILE}"
|
|
gh issue create -R rustfs/backlog --title "${TITLE}" \
|
|
--body-file "${BODY_FILE}" --label functional-test \
|
|
|| gh issue create -R rustfs/backlog --title "${TITLE}" --body-file "${BODY_FILE}" \
|
|
|| echo "could not file the stall alert issue either; check the token" >&2
|
|
exit 1
|
|
fi
|
|
|
|
- name: Notify on failure
|
|
if: failure()
|
|
run: |
|
|
echo "RustFS upgrade compatibility test failed"
|
|
echo "From: ${{ inputs.from_url || inputs.from_version || 'release (default)' }}"
|
|
echo "To: ${{ inputs.to_url || inputs.to_version || 'nightly (R2 latest)' }}"
|
|
echo "See the uploaded report and logs for details."
|