diff --git a/.github/workflows/api-verification.yml b/.github/workflows/api-verification.yml new file mode 100644 index 00000000000..41651fd40ad --- /dev/null +++ b/.github/workflows/api-verification.yml @@ -0,0 +1,120 @@ +name: "API Verification" +on: + workflow_run: + workflows: [Ubuntu packaging] + types: + - completed + +env: + STATUS_CONTEXT: 'API Verification' + PKG_NAME: 'libkeymancore' + +jobs: + setup_environment: + runs-on: ubuntu-latest + outputs: + VERSION: ${{ steps.environment_step.outputs.VERSION }} + PRERELEASE_TAG: ${{ steps.environment_step.outputs.PRERELEASE_TAG }} + GIT_SHA: ${{ steps.environment_step.outputs.GIT_SHA }} + GIT_BASE: ${{ steps.environment_step.outputs.GIT_BASE }} + IS_TEST_BUILD: ${{ steps.environment_step.outputs.IS_TEST_BUILD }} + GIT_BRANCH: ${{ steps.environment_step.outputs.GIT_BRANCH }} + GIT_BASE_BRANCH: ${{ steps.environment_step.outputs.GIT_BASE_BRANCH }} + GIT_USER: ${{ steps.environment_step.outputs.GIT_USER }} + + steps: + - name: Restore artifacts + uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 + with: + path: | + artifacts + key: artifacts-key-${GITHUB_RUN_ID} + restore-keys: artifacts-key- + + - name: Read environment + id: environment_step + run: | + cat artifacts/env >> $GITHUB_OUTPUT + + api_verification: + name: Verify API for libkeymancore.so + needs: setup_environment + runs-on: ubuntu-latest + + steps: + - name: Set pending status on PR builds + id: set_status + if: needs.setup_environment.outputs.IS_TEST_BUILD == 'true' + shell: bash + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + /repos/$GITHUB_REPOSITORY/statuses/${{ needs.setup_environment.outputs.GIT_SHA }} \ + -f state='pending' \ + -f target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \ + -f description='API verification started' \ + -f context="$STATUS_CONTEXT" + + - name: Checkout + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 + with: + ref: '${{ needs.setup_environment.outputs.GIT_SHA }}' + fetch-depth: 0 + + - name: Install devscripts + uses: ./.github/actions/apt-install + with: + packages: devscripts equivs + + - name: "Verify API for libkeymancore.so (${{ needs.setup_environment.outputs.GIT_BRANCH }}, branch ${{ needs.setup_environment.outputs.GIT_BASE_BRANCH }}, by ${{ needs.setup_environment.outputs.GIT_USER }}) - " + run: | + cd linux + ./scripts/deb-packaging.sh \ + --gha \ + --bin-pkg "${GITHUB_WORKSPACE}/artifacts/${PKG_NAME}_${{ needs.setup_environment.outputs.VERSION }}-1${{ needs.setup_environment.outputs.PRERELEASE_TAG }}+$(lsb_release -c -s)1_amd64.deb" \ + --git-sha "${{ needs.setup_environment.outputs.GIT_SHA }}" \ + --git-base "${{ needs.setup_environment.outputs.GIT_BASE }}" \ + verify 2>> $GITHUB_STEP_SUMMARY + + - name: Archive .symbols file + uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 + with: + name: libkeymancore.symbols + path: linux/debian/tmp/DEBIAN/symbols + if: always() + + set_status: + name: Set result status on PR builds + needs: [setup_environment, api_verification] + runs-on: ubuntu-latest + if: ${{ always() && needs.setup_environment.outputs.IS_TEST_BUILD == 'true' }} + steps: + - name: Set success + if: needs.api_verification.result == 'success' + run: | + echo "RESULT=success" >> $GITHUB_ENV + echo "MSG=Package build succeeded" >> $GITHUB_ENV + + - name: Set cancelled + if: needs.api_verification.result == 'cancelled' + run: | + echo "RESULT=error" >> $GITHUB_ENV + echo "MSG=Package build cancelled" >> $GITHUB_ENV + + - name: Set failure + if: needs.api_verification.result == 'failure' + run: | + echo "RESULT=failure" >> $GITHUB_ENV + echo "MSG=Package build failed" >> $GITHUB_ENV + + - name: Set final status + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + /repos/$GITHUB_REPOSITORY/statuses/${{ needs.setup_environment.outputs.GIT_SHA }} \ + -f state="$RESULT" \ + -f target_url="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" \ + -f description="$MSG" \ + -f context="$STATUS_CONTEXT" diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml index 834ef4b892f..694a3757a16 100644 --- a/.github/workflows/deb-packaging.yml +++ b/.github/workflows/deb-packaging.yml @@ -30,7 +30,7 @@ jobs: PRERELEASE_TAG: ${{ steps.prerelease_tag.outputs.PRERELEASE_TAG }} steps: - name: Checkout - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c #v3.3.0 + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 with: ref: '${{ github.event.client_payload.buildSha }}' @@ -254,67 +254,56 @@ jobs: done echo "::endgroup::" - api_verification: + prepare_api_verification: name: Verify API for libkeymancore.so needs: [sourcepackage, binary_packages] runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #v4.1.1 - with: - ref: '${{ github.event.client_payload.buildSha }}' - fetch-depth: 0 - - name: Download Artifacts uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 with: path: artifacts merge-multiple: true - - name: Install devscripts - uses: ./.github/actions/apt-install - with: - packages: devscripts equivs - - - name: Verify API + - name: Save environment run: | - cd linux - PKG_NAME=libkeymancore - ./scripts/deb-packaging.sh \ - --gha \ - --bin-pkg "${GITHUB_WORKSPACE}/artifacts/${PKG_NAME}_${{ needs.sourcepackage.outputs.VERSION }}-1${{ needs.sourcepackage.outputs.PRERELEASE_TAG }}+jammy1_amd64.deb" \ - --git-sha "${{ github.event.client_payload.buildSha }}" \ - --git-base "${{ github.event.client_payload.baseRef }}" \ - verify 2>> $GITHUB_STEP_SUMMARY - - - name: Archive .symbols file - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 + echo "VERSION=${{ needs.sourcepackage.outputs.VERSION }}" > artifacts/env + echo "PRERELEASE_TAG=${{ needs.sourcepackage.outputs.PRERELEASE_TAG }}" >> artifacts/env + echo "GIT_SHA=${{ github.event.client_payload.buildSha }}" >> artifacts/env + echo "GIT_BASE=${{ github.event.client_payload.baseRef }}" >> artifacts/env + echo "IS_TEST_BUILD=${{ github.event.client_payload.isTestBuild }}" >> artifacts/env + echo "GIT_BRANCH=${{ github.event.client_payload.branch }}" >> artifacts/env + echo "GIT_BASE_BRANCH=${{ github.event.client_payload.baseBranch }}" >> artifacts/env + echo "GIT_USER=${{ github.event.client_payload.user }}" >> artifacts/env + + - name: Cache artifacts + uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 with: - name: libkeymancore.symbols - path: linux/debian/tmp/DEBIAN/symbols - if: always() + path: | + artifacts + key: artifacts-key-${GITHUB_RUN_ID} set_status: name: Set result status on PR builds - needs: [sourcepackage, binary_packages, api_verification] + needs: [sourcepackage, binary_packages, prepare_api_verification] runs-on: ubuntu-latest if: ${{ always() && github.event.client_payload.isTestBuild == 'true' }} steps: - name: Set success - if: needs.sourcepackage.result == 'success' && needs.binary_packages.result == 'success' && needs.api_verification.result == 'success' + if: needs.sourcepackage.result == 'success' && needs.binary_packages.result == 'success' && needs.prepare_api_verification.result == 'success' run: | echo "RESULT=success" >> $GITHUB_ENV echo "MSG=Package build succeeded" >> $GITHUB_ENV - name: Set cancelled - if: needs.sourcepackage.result == 'cancelled' || needs.binary_packages.result == 'cancelled' || needs.api_verification.result == 'cancelled' + if: needs.sourcepackage.result == 'cancelled' || needs.binary_packages.result == 'cancelled' || needs.prepare_api_verification.result == 'cancelled' run: | echo "RESULT=error" >> $GITHUB_ENV echo "MSG=Package build cancelled" >> $GITHUB_ENV - name: Set failure - if: needs.sourcepackage.result == 'failure' || needs.binary_packages.result == 'failure' || needs.api_verification.result == 'failure' + if: needs.sourcepackage.result == 'failure' || needs.binary_packages.result == 'failure' || needs.prepare_api_verification.result == 'failure' run: | echo "RESULT=failure" >> $GITHUB_ENV echo "MSG=Package build failed" >> $GITHUB_ENV diff --git a/docs/core-api-verification.md b/docs/core-api-verification.md index 619e7a9b352..ccce1908957 100644 --- a/docs/core-api-verification.md +++ b/docs/core-api-verification.md @@ -1,6 +1,6 @@ # Keyman Core API verification -During GHA Debian package build we verify that the API didn't change +After the GHA Debian package build we verify that the API didn't change without being documented in `linux/debian/libkeymancore.symbols`. [Debian policy](https://www.debian.org/doc/debian-policy/ch-sharedlibs#run-time-shared-libraries) @@ -21,7 +21,7 @@ have to begin with a space character. Example: -``` +```text km_core_actions_dispose@Base 17.0.197 ``` @@ -51,13 +51,13 @@ instantiations. To work around this, we list the C++ symbols as `optional` that get flaged: -``` +```text (c++|optional)"typeinfo name for std::codecvt_utf8_utf16@Base" 17.0.244 ``` `dpkg-gensymbols` will report the mangled C++ name in the diff, e.g. -``` +```text + _ZTSSt18codecvt_utf8_utf16IDsLm1114111ELSt12codecvt_mode0EE@Base 17.0.244 ``` @@ -70,7 +70,7 @@ echo "_ZTSSt18codecvt_utf8_utf16IDsLm1114111ELSt12codecvt_mode0EE@Base" | c++fil which will output the demangled name: -``` +```text typeinfo name for std::codecvt_utf8_utf16@Base ``` @@ -101,7 +101,7 @@ match the API verification will fail. ## How this works -`.github/workflows/deb-packaging.yml` contains a `Verify API` step +`.github/workflows/api-verification.yml` contains a `Verify API` step which will call `linux/scripts/deb-packaging.sh` with the `verify` parameter. Before calling the script it will download and extract the binary package artifacts.