Skip to content

Move Validate Catalog Metadata step at the end of the workflow #2

Move Validate Catalog Metadata step at the end of the workflow

Move Validate Catalog Metadata step at the end of the workflow #2

name: Check Backstage Version Compatibility

Check failure on line 1 in .github/workflows/check-backstage-compatibility.yaml

View workflow run for this annotation

GitHub Actions / .github/workflows/check-backstage-compatibility.yaml

Invalid workflow file

(Line: 84, Col: 9): 'name' is already defined, (Line: 85, Col: 9): Unexpected value 'uses', (Line: 86, Col: 9): Unexpected value 'with'
on:
workflow_call:
inputs:
workspace-path:
description: Relative path of a single workspace on which the compatibility check workflow should be applied.
required: false
type: string
overlay-branch:
description: Branch of the overlay structure (current branch by default).
type: string
required: false
default: ''
overlay-repo:
description: Repository of the overlay structure (`github.repository` by default).
type: string
required: false
default: ''
fail-for-required-only:
description: Fail only when some required workspaces are incompatible.
type: boolean
required: false
default: false
debug:
type: boolean
required: false
default: false
outputs:
incompatible-required-workspaces:
value: '${{ jobs.check.outputs.incompatible-required-workspaces }}'
incompatible-unrequired-workspaces:
value: '${{ jobs.check.outputs.incompatible-unrequired-workspaces }}'
jobs:
check:
runs-on: ubuntu-latest
name: Check
outputs:
incompatible-required-workspaces: ${{ steps.check-workspaces.outputs.INCOMPATIBLE_REQUIRED_WORKSPACES }}
incompatible-unrequired-workspaces: ${{ steps.check-workspaces.outputs.INCOMPATIBLE_UNREQUIRED_WORKSPACES }}
steps:
- name: Validate Inputs
uses: actions/github-script@v7
env:
INPUT_WORKSPACE_PATH: ${{ inputs.workspace-path }}
with:
script: |
const workspacePath = core.getInput('workspace_path');
if (workspacePath.startsWith('/') ||workspacePath.includes('..')) {
core.setFailed(`Invalid workspace path: ${workspacePath}`);
}
- name: Set overlay_ref
id: set-overlay-repo-ref
env:
INPUT_OVERLAY_BRANCH: ${{ inputs.overlay-branch }}
run: |
if [[ "${INPUT_OVERLAY_BRANCH}" != "" ]]
then
echo "OVERLAY_REPO_REF=${INPUT_OVERLAY_BRANCH}" >> $GITHUB_OUTPUT
else
echo "OVERLAY_REPO_REF=${{ github.head_ref || github.ref_name }}" >> $GITHUB_OUTPUT
fi
- name: Set overlay_repo
id: set-overlay-repo
env:
INPUT_OVERLAY_REPO: ${{ inputs.overlay-repo }}
run: |
if [[ "${INPUT_OVERLAY_REPO}" != "" ]]
then
echo "OVERLAY_REPO=${INPUT_OVERLAY_REPO}" >> $GITHUB_OUTPUT
else
echo "OVERLAY_REPO=${{ github.repository }}" >> $GITHUB_OUTPUT
fi
name: Checkout overlay repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ steps.set-overlay-repo-ref.outputs.OVERLAY_REPO_REF }}
repository: ${{ steps.set-overlay-repo.outputs.OVERLAY_REPO }}
- name: Download the required-plugins artifact
uses: actions/download-artifact@v4
continue-on-error: true
with:
name: required-plugins
- name: Check workspaces
id: check-workspaces
shell: bash
env:
INPUT_WORKSPACE_PATH: ${{ inputs.workspace-path }}
INPUT_FAIL_FOR_REQUIRED_ONLY: ${{ inputs.fail-for-required-only }}
INPUT_OVERLAY_REPO: ${{ steps.set-overlay-repo.outputs.OVERLAY_REPO }}
INPUT_OVERLAY_REPO_REF: ${{ steps.set-overlay-repo-ref.outputs.OVERLAY_REPO_REF }}
run: |
npm install semver -g
if [[ "${{ inputs.debug }}" == "true" ]]
then
set -x
fi
echo -n "" >> required-plugins
targetBackstageVersion=$(jq -r '.backstage' versions.json)
workspacePath=''
if [[ "${INPUT_WORKSPACE_PATH}" != "" ]]
then
workspacePath="${INPUT_WORKSPACE_PATH}"
elif [[ "${{ github.head_ref }}" == "workspaces/"* ]]
then
workspacePath="$(echo '${{ github.head_ref }}' | sed -e 's:workspaces/[^_]*__\(.*\)$:workspaces/\1:')"
fi
declare -A incompatibleRequiredWorkspaces
declare -A incompatibleUnrequiredWorkspaces
declare -A infos
for d in $(find workspaces -mindepth 1 -maxdepth 1 -type d)
do
if [[ "${workspacePath}" != "" ]] && [[ "${workspacePath}" != "$d" ]]
then
continue
fi
if [[ -f "${d}/plugins-list.yaml" ]] && [[ -f "${d}/source.json" ]]
then
sourceBackstageVersion=$(jq -r '.["repo-backstage-version"] // ""' "${d}/source.json")
workspaceBackstageVersion="${sourceBackstageVersion}"
# If the workspace has an overridden backstage.json file in the overlay, use it to check the backstage version compatibility
if [[ -f "${d}/backstage.json" ]]
then
workspaceBackstageVersion=$(jq -r '.version' "${d}/backstage.json")
fi
incompatibleVersion=""
if [[ "${workspaceBackstageVersion}" == "" ]]
then
incompatibleVersion="*not found*"
elif [[ "${targetBackstageVersion}" != "$(semver -r ~${workspaceBackstageVersion} ${targetBackstageVersion})" ]]
then
incompatibleVersion="${sourceBackstageVersion}"
if [[ "${incompatibleVersion}" == "" ]]
then
incompatibleVersion="*not found*"
fi
fi
if [[ "${incompatibleVersion}" != "" ]]
then
if grep -e "^${d#*/}" required-plugins &> /dev/null
then
incompatibleRequiredWorkspaces["${d}"]="${incompatibleVersion}"
else
incompatibleUnrequiredWorkspaces["${d}"]="${incompatibleVersion}"
fi
infos["${d}"]=""
if curl -fs "https://github.com/${INPUT_OVERLAY_REPO}/tree/workspaces/${INPUT_OVERLAY_REPO_REF}__${d#workspaces/}" &> /dev/null
then
infos["${d}"]="${infos[${d}]}[Automatic PR](https://github.com/${INPUT_OVERLAY_REPO}/pulls?q=is:pr+is:open+head:workspaces/${INPUT_OVERLAY_REPO_REF}__${d#workspaces/})"
fi
if [[ "${infos[${d}]}" == "" ]]
then
githubRepo=$(jq -r '.repo' "${d}/source.json")
workspaceSubFolder="${d}/"
repoFlat=$(jq -r '.["repo-flat"]' "${d}/source.json")
if [[ "${repoFlat}" == "true" ]]
then
workspaceSubFolder=""
fi
if curl -fs "${githubRepo}/blob/main/${workspaceSubFolder}backstage.json" &> /dev/null
then
infos["${d}"]="[BS Version History](${githubRepo}/commits/main/${workspaceSubFolder}backstage.json)"
fi
fi
fi
fi
done
echo "INCOMPATIBLE_REQUIRED_WORKSPACES<<EOF" >> $GITHUB_OUTPUT
for key in "${!incompatibleRequiredWorkspaces[@]}"
do
echo "${key}" >> $GITHUB_OUTPUT
done
echo "EOF" >> $GITHUB_OUTPUT
echo "INCOMPATIBLE_UNREQUIRED_WORKSPACES<<EOF" >> $GITHUB_OUTPUT
for key in "${!incompatibleUnrequiredWorkspaces[@]}"
do
echo "${key}" >> $GITHUB_OUTPUT
done
echo "EOF" >> $GITHUB_OUTPUT
required=${#incompatibleRequiredWorkspaces[@]}
optional=${#incompatibleUnrequiredWorkspaces[@]}
if [[ ${required} -gt 0 || ${optional} -gt 0 ]]
then
message="$((${optional}+${required})) incompatible workspaces, ${required} of which are mandatory"
if [[ ${required} -eq 0 && "${INPUT_FAIL_FOR_REQUIRED_ONLY}" == "true" ]]
then
echo "::warning title=Incompatible backstage versions::${message}."
else
echo "::error title=Incompatible backstage versions::${message}."
fi
# Create compatibility report markdown file
REPORT_FILE="backstage-compatibility-report.md"
# Write markdown content to both file and step summary
{
echo "#### Backstage-incompatible workspaces"
echo ""
echo "Some workspaces have a backstage version (in sources or in their overlay folder) which is *__incompatible__* with the target Backstage version (\`${targetBackstageVersion}\`)."
echo "${message}:"
echo "| Folder | Backstage version | Mandatory | Info |"
echo "|--------|-------------------|-----------|-------|"
for key in "${!incompatibleRequiredWorkspaces[@]}"
do
echo "| [${key}](https://github.com/${INPUT_OVERLAY_REPO}/tree/${INPUT_OVERLAY_REPO_REF}/${key}) | ${incompatibleRequiredWorkspaces[$key]} | :red_circle: | ${infos[$key]} |"
done
for key in "${!incompatibleUnrequiredWorkspaces[@]}"
do
echo "| [${key}](https://github.com/${INPUT_OVERLAY_REPO}/tree/${INPUT_OVERLAY_REPO_REF}/${key}) | ${incompatibleUnrequiredWorkspaces[$key]} | :white_circle: | ${infos[$key]} |"
done
echo ""
echo "<details>"
echo "<summary><strong>How to fix</strong></summary>"
echo ""
echo "You have 3 main options:"
echo '- *__Use the already-opened PR :__* For automatically-discovered workspaces, there might already be an automatically-opened PR that updates the commit to the target backstage version (`Automatic PR` link in column 4 above): just publish the plugins and test them from the PR by following the PR instructions.'
echo '- *__Manually update the workspace commit :__*'
echo ' - Find a newer commit, with a backstage version compatible with the target backstage version :__*'
echo ' - *__Backstage version history available__*: A `BS Version History` link might be available in column 4: in the workspace source repository, it points to the list of commits touching the `backstage.json` file. This would help you finding out whether this workspace has a commit that has been published for the target backstage version.'
echo ' - *__No info available__*: If no information is is provided in column 4, the `backstage.json` probably does not exist in workspace sources. You would have to look deeper into the newer commits of workspace sources, possibly in the low-level dependencies in the `package.json` files, to find out a commit with an underlying backstage version compatible with the target backstage version.'
echo ' - Then, in the overlay repository, update the `repo-ref` field of the `source.json` file to the new source commit, and remember to also change the `repo-backstage-version` field to the corresponding compatible backstage version.'
echo '- *__No compatible commit :__* If the workspace sources contain __*no compatible newer commit*__ ( == a commit that provides a `backstage.json` version compatible with the target backstage), but the current workspace commit is known to work with the target backstage version, then you can override the declared backstage version compatibility for this workspace commit in the overlay repository: add a `backstage.json` file at the root of the overlay workspace folder with the desired target backstage version. This would require full testing of the workspace plugins on the target backstage though.'
echo ""
echo "</details>"
} | tee -a "$REPORT_FILE" >> $GITHUB_STEP_SUMMARY
if [[ "${INPUT_FAIL_FOR_REQUIRED_ONLY}" != "true" ]]
then
exit 1
fi
if [[ ${required} -gt 0 ]]
then
exit 1
fi
else
# Create empty report file when there are no incompatible workspaces
REPORT_FILE="backstage-compatibility-report.md"
{
echo "#### Backstage Compatibility Check"
echo ""
echo "✅ All workspaces are compatible with the target Backstage version (\`${targetBackstageVersion}\`)."
echo ""
echo "_No action required._"
} > "$REPORT_FILE"
fi
- name: Upload compatibility report
uses: actions/upload-artifact@v4
if: always()
with:
name: backstage-compatibility-report
path: backstage-compatibility-report.md
retention-days: 30