From 8caa73c5005297593a7f50c1b4e225efc3a9e38f Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Wed, 10 Aug 2022 12:28:38 +0200 Subject: [PATCH] feat(linux): Add debian packaging GHA --- .github/actions/apt-install/action.yml | 19 ++ .github/workflows/deb-packaging.yml | 205 ++++++++++++++++++++ resources/build/increment-version.sh | 2 +- resources/build/run-required-test-builds.sh | 4 + resources/build/trigger-builds.inc.sh | 40 ++++ resources/build/trigger-definitions.inc.sh | 11 +- 6 files changed, 275 insertions(+), 6 deletions(-) create mode 100644 .github/actions/apt-install/action.yml create mode 100644 .github/workflows/deb-packaging.yml diff --git a/.github/actions/apt-install/action.yml b/.github/actions/apt-install/action.yml new file mode 100644 index 0000000000..64cb1b91dc --- /dev/null +++ b/.github/actions/apt-install/action.yml @@ -0,0 +1,19 @@ +name: apt-install +description: | + Install debian packages with apt +inputs: + packages: + description: Packages to install + default: devscripts equivs + required: false +runs: + using: "composite" + steps: + - name: Install packages + shell: bash + run: | + export DEBIAN_FRONTEND=noninteractive + export DEBIAN_PRIORITY=critical + export DEBCONF_NOWARNINGS=yes + sudo apt-get update + sudo apt-get install -q -y ${{ inputs.packages }} diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml new file mode 100644 index 0000000000..be71ad8792 --- /dev/null +++ b/.github/workflows/deb-packaging.yml @@ -0,0 +1,205 @@ +name: "Ubuntu packaging" +on: + repository_dispatch: + types: ['deb-packaging'] + +jobs: + sourcepackage: + name: Build source package + runs-on: ubuntu-22.04 + outputs: + VERSION: ${{ steps.version_step.outputs.VERSION }} + PRERELEASE_TAG: ${{ steps.prerelease_tag.outputs.PRERELEASE_TAG }} + steps: + - name: Checkout + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3.0.2 + with: + ref: '${{ github.event.client_payload.ref }}' + + - name: Install devscripts + uses: ./.github/actions/apt-install + with: + packages: devscripts equivs + + - name: Install dependencies + run: | + cd linux + sudo mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control + + - name: Build source package + run: | + cd linux + tier="stable" + + echo "Make source package for keyman" + echo "reconfigure" + JENKINS="yes" TIER="$tier" ./scripts/reconf.sh keyman + + echo "Make origdist" + ./scripts/dist.sh origdist keyman + echo "Make deb source" + ./scripts/deb.sh sourcepackage keyman + + mv builddebs/* .. + + - name: Set version as output parameter + id: version_step + shell: bash + run: | + THIS_SCRIPT="$GITHUB_WORKSPACE/.github/workflows/deb-packaging.yml" + . "resources/build/build-utils.sh" + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT + + - name: Set prerelease tag as output parameter + id: prerelease_tag + shell: bash + run: | + if [ "${{ github.event.client_payload.isTestBuild }}" == "true" ]; then + PRERELEASE_TAG="~${{ github.event.client_payload.branch }}-$GITHUB_RUN_NUMBER.$GITHUB_RUN_ATTEMPT" + else + PRERELEASE_TAG="" + fi + echo "PRERELEASE_TAG=$PRERELEASE_TAG" >> $GITHUB_OUTPUT + + - name: Output which branch or PR we're building plus name of .dsc file + run: | + if [ "${{ github.event.client_payload.isTestBuild }}" == "true" ]; then + echo ":checkered_flag: **Test build of version ${{ steps.version_step.outputs.VERSION }} for ${{ github.event.client_payload.branch }}**" >> $GITHUB_STEP_SUMMARY + else + echo ":ship: **Release build of ${{ github.event.client_payload.branch }} branch (${{ github.event.client_payload.ref}}), version ${{ steps.version_step.outputs.VERSION }}**" >> $GITHUB_STEP_SUMMARY + fi + echo "" >> $GITHUB_STEP_SUMMARY + echo ":gift: Generated source package:" >> $GITHUB_STEP_SUMMARY + echo "- $(find . -name keyman_\*.dsc)" >> $GITHUB_STEP_SUMMARY + + - name: Store source package + uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 + with: + name: keyman-srcpkg + path: | + keyman_* + debian/***/* + if: always() + + binary_packages: + name: Build binary packages + needs: sourcepackage + strategy: + fail-fast: true + matrix: + dist: [focal, jammy, kinetic] + arch: [amd64] + + runs-on: ubuntu-latest + steps: + - name: Download Artifacts + uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # v3.0.0 + with: + path: artifacts + + - name: Build + uses: sillsdev/gha-ubuntu-packaging@63b12dd80a1ee58cae16a7e3a13ff9d3d4002ba1 # v0.2 + with: + dist: "${{ matrix.dist }}" + platform: "${{ matrix.arch }}" + source_dir: "artifacts/keyman-srcpkg" + sourcepackage: "keyman_${{ needs.sourcepackage.outputs.VERSION }}-1.dsc" + deb_fullname: "Keyman GHA packager" + deb_email: "support@keyman.com" + prerelease_tag: ${{ needs.sourcepackage.outputs.PRERELEASE_TAG }} + + - name: Output resulting .deb files + run: | + echo '```' >> $GITHUB_STEP_SUMMARY + echo "$(find artifacts/ -name \*.deb)" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + + - name: Store binary packages + uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 + with: + name: keyman-binarypkgs + path: | + artifacts/* + !artifacts/keyman-srcpkg/ + if: always() + + deb_signing: + name: Sign source and binary packages + needs: [sourcepackage, binary_packages] + runs-on: ubuntu-latest + environment: deploy + + steps: + - name: Sign packages + uses: sillsdev/gha-deb-signing@c035bafb5cd334191b6943d063743a619750b016 # v0.1 + with: + src-pkg-path: "artifacts/keyman-srcpkg" + src-pkg-name: "keyman_${{ needs.sourcepackage.outputs.VERSION }}-1_source.changes" + bin-pkg-path: "artifacts/keyman-binarypkgs" + bin-pkg-name: "keyman_${{ needs.sourcepackage.outputs.VERSION }}-1${{ needs.sourcepackage.outputs.PRERELEASE_TAG }}+" + artifacts-name: "keyman-signedpkgs" + gpg-signing-key: "${{ secrets.GPG_SIGNING_KEY }}" + debsign-keyid: "${{ secrets.DEBSIGN_KEYID }}" + + # TODO: upload not yet possible - will need a self-hosted runner inside of + # the VPN to do that. + + # upload-to-llso: + # name: Upload packages to llso + # needs: deb_signing + # runs-on: ubuntu-latest + # environment: deploy + + # steps: + # - name: Configure GPG Key + # run: | + # echo -n "${{ secrets.GPG_SIGNING_KEY }}" | base64 --decode | gpg --import + + # - name: Download Artifacts + # uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # v3.0.0 + # with: + # path: artifacts + + # - name: Upload + # run: echo "Upload..." + + api_verification: + name: Verify API for libkmnkbp0.so + needs: [sourcepackage, binary_packages] + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b #v3.0.2 + with: + ref: '${{ github.event.client_payload.ref }}' + + - name: Download Artifacts + uses: actions/download-artifact@fb598a63ae348fa914e94cd0ff38f362e927b741 # v3.0.0 + with: + path: artifacts + + - name: Install devscripts + uses: ./.github/actions/apt-install + with: + packages: devscripts equivs + + - name: Verify API + run: | + tar xf "artifacts/keyman-srcpkg/keyman_${{ needs.sourcepackage.outputs.VERSION }}-1.debian.tar.xz" + if [ ! -f debian/libkmnkbp0-0.symbols ]; then + echo ":warning: Missing libkmnkbp0-0.symbols file" >> $GITHUB_STEP_SUMMARY + else + tmpDir=$(mktemp -d) + dpkg -x "artifacts/keyman-binarypkgs/libkmnkbp0-0_${{ needs.sourcepackage.outputs.VERSION }}-1${{ needs.sourcepackage.outputs.PRERELEASE_TAG }}+jammy1_amd64.deb" $tmpDir + cd debian + dpkg-gensymbols -v${{ needs.sourcepackage.outputs.VERSION }} -plibkmnkbp0-0 -e${tmpDir}/usr/lib/x86_64-linux-gnu/libkmnkbp0.so* -Olibkmnkbp0-0.symbols -c4 + echo ":heavy_check_mark: libkmnkbp0-0 API didn't change" >> $GITHUB_STEP_SUMMARY + fi + + - name: Archive .symbols file + uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0 + with: + name: libkmnkbp0-0.symbols + path: debian/libkmnkbp0-0.symbols + if: always() diff --git a/resources/build/increment-version.sh b/resources/build/increment-version.sh index fd0bc7add8..4e57f04cb3 100755 --- a/resources/build/increment-version.sh +++ b/resources/build/increment-version.sh @@ -143,7 +143,7 @@ if [ "$action" == "commit" ]; then popd > /dev/null # - # Trigger builds for the previous version on TeamCity and Jenkins + # Trigger builds for the previous version on TeamCity, Jenkins and GitHub # triggerBuilds diff --git a/resources/build/run-required-test-builds.sh b/resources/build/run-required-test-builds.sh index 5213c6b5c7..3dbaee1a82 100755 --- a/resources/build/run-required-test-builds.sh +++ b/resources/build/run-required-test-builds.sh @@ -58,6 +58,10 @@ function triggerTestBuilds() { local job=${test_build%_Jenkins} echo " -- Triggering build configuration $job/$branch on Jenkins" triggerJenkinsBuild "$job" "$branch" "$force" + elif [ "${test_build:(-7)}" == "_GitHub" ]; then + local job=${test_build%_GitHub} + echo " -- Triggering GitHub action build $job/$branch" + triggerGitHubActionsBuild true "$job" "$branch" else echo " -- Triggering build configuration $test_build on teamcity" triggerTeamCityBuild true "$test_build" "$vcs_test" "$branch" diff --git a/resources/build/trigger-builds.inc.sh b/resources/build/trigger-builds.inc.sh index 9660bd4b74..43cf11e81e 100644 --- a/resources/build/trigger-builds.inc.sh +++ b/resources/build/trigger-builds.inc.sh @@ -21,6 +21,10 @@ function triggerBuilds() { local job=${build%_Jenkins} echo Triggering Jenkins build "$job" "$base" "true" triggerJenkinsBuild "$job" "$base" "true" + elif [ "${build:(-7)}" == "_GitHub" ]; then + local job=${build%_GitHub} + echo Triggering GitHub action build "$job" "$base" + triggerGitHubActionsBuild false "$job" "$base" else echo Triggering TeamCity build false $build $TEAMCITY_VCS_ID $base triggerTeamCityBuild false $build $TEAMCITY_VCS_ID $base @@ -120,3 +124,39 @@ function triggerJenkinsBuild() { echo fi } + +function triggerGitHubActionsBuild() { + local IS_TEST_BUILD="$1" + local GITHUB_ACTION="$2" + local GIT_BRANCH="${3:-master}" + local GIT_REF=$GIT_BRANCH + + local GITHUB_SERVER=https://api.github.com/repos/keymanapp/keyman/dispatches + + # This will only be true if we created and pushed a tag + if [ "${action:-""}" == "commit" ]; then + GIT_REF="release-$VERSION_WITH_TAG" + fi + + if [[ $GIT_BRANCH != stable-* ]] && [[ $GIT_BRANCH =~ [0-9]+ ]]; then + GIT_BRANCH="PR-${GIT_BRANCH}" + fi + + local DATA="{\"event_type\": \"$GITHUB_ACTION\", \ + \"client_payload\": { \ + \"ref\": \"$GIT_REF\", \ + \"branch\": \"$GIT_BRANCH\", \ + \"isTestBuild\": \"$IS_TEST_BUILD\" \ + }}" + + echo "GitHub Action Data: $DATA" + + # adjust indentation for output of curl + echo -n " " + curl --silent --write-out '\n' \ + --request POST \ + --header "Accept: application/vnd.github+json" \ + --header "Authorization: token $GITHUB_TOKEN" \ + --data "$DATA" \ + $GITHUB_SERVER +} diff --git a/resources/build/trigger-definitions.inc.sh b/resources/build/trigger-definitions.inc.sh index 9224d407df..99977a06ce 100644 --- a/resources/build/trigger-definitions.inc.sh +++ b/resources/build/trigger-definitions.inc.sh @@ -27,6 +27,7 @@ watch_developer='common|core|web' # _Jenkins should be appended to any build configuration (pipeline) name that is from Jenkins, # not TeamCity. # +# _GitHub should be appended to any build configuration name that is from GitHub, not TeamCity. # Test Build Configurations @@ -35,7 +36,7 @@ bc_test_all=() bc_test_android=(KeymanAndroid_TestPullRequests KeymanAndroid_TestSamplesAndTestProjects) bc_test_ios=(Keyman_iOS_TestPullRequests Keyman_iOS_TestSamplesAndTestProjects) -bc_test_linux=(KeymanLinux_TestPullRequests Keyman_Common_KPAPI_TestPullRequests_Linux pipeline-keyman-packaging_Jenkins) +bc_test_linux=(KeymanLinux_TestPullRequests Keyman_Common_KPAPI_TestPullRequests_Linux pipeline-keyman-packaging_Jenkins deb-packaging_GitHub) bc_test_mac=(Keyman_KeymanMac_PullRequests Keyman_Common_KPAPI_TestPullRequests_macOS) bc_test_windows=(KeymanDesktop_TestPullRequests KeymanDesktop_TestPrRenderOnScreenKeyboards Keyman_Common_KPAPI_TestPullRequests_Windows) bc_test_web=(Keymanweb_TestPullRequests Keyman_Common_LMLayer_TestPullRequests Keyman_Common_KPAPI_TestPullRequests_WASM) @@ -49,7 +50,7 @@ vcs_test=HttpsGithubComKeymanappKeymanPRs bc_master_android=(KeymanAndroid_Build) bc_master_ios=(Keyman_iOS_Master) -bc_master_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins) +bc_master_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins deb-packaging_GitHub) bc_master_mac=(KeymanMac_Master) bc_master_windows=(Keyman_Build) bc_master_web=(Keymanweb_Build) @@ -61,7 +62,7 @@ vcs_master=HttpsGithubComKeymanappKeyman bc_beta_android=(KeymanAndroid_Build) bc_beta_ios=(Keyman_iOS_Master) -bc_beta_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins) +bc_beta_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins deb-packaging_GitHub) bc_beta_mac=(KeymanMac_Master) bc_beta_windows=(Keyman_Build) bc_beta_web=(Keymanweb_Build) @@ -73,7 +74,7 @@ vcs_beta=HttpsGithubComKeymanappKeyman bc_stable_14_0_android=(KeymanAndroid_Build) bc_stable_14_0_ios=(Keyman_iOS_Master) -bc_stable_14_0_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins) +bc_stable_14_0_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins deb-packaging_GitHub) bc_stable_14_0_mac=(KeymanMac_Master) bc_stable_14_0_windows=(Keyman_Build) bc_stable_14_0_web=(Keymanweb_Build) @@ -88,7 +89,7 @@ vcs_stable_14_0=HttpsGithubComKeymanappKeyman bc_stable_15_0_android=(KeymanAndroid_Build) bc_stable_15_0_ios=(Keyman_iOS_Master) -bc_stable_15_0_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins) +bc_stable_15_0_linux=(KeymanLinux_Master pipeline-keyman-packaging_Jenkins deb-packaging_GitHub) bc_stable_15_0_mac=(KeymanMac_Master) bc_stable_15_0_windows=(Keyman_Build) bc_stable_15_0_web=(Keymanweb_Build)