Move Validate Catalog Metadata step at the end of the workflow #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Check Backstage Version Compatibility | ||
|
Check failure on line 1 in .github/workflows/check-backstage-compatibility.yaml
|
||
| 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 | ||