diff --git a/.github/workflows/buildRelease.yml b/.github/workflows/buildRelease.yml new file mode 100644 index 0000000..7cebfac --- /dev/null +++ b/.github/workflows/buildRelease.yml @@ -0,0 +1,430 @@ +#******************************************************************************* +# buidReleaseInclDocker.yml +# +# Workflow to build a Maiko release that is pushed to github as well as +# Docker images incorporating the release, which are pushed to Docker Hub. +# For linux: release assets are built/pushed for X86_64, aarch64 and arm7vl and +# a multiplatform Docker image is pushed. +# For macOS: release assets are built/pushed for X86_64. (No aarch64 as yet.) +# For Windows: not supported +# +# Note release pushed to github automatically includes source code assets +# in tar and zip formats. +# +# 2022-01-16 by Frank Halasz based on earlier workflow called buildDocker.yml +# +# Copyright 2022 by Interlisp.org +# +# +# ****************************************************************************** + +name: 'Build/Push Release & Docker Image' + +env: + workflow: 'buildReleaseInclDocker.yml' + +# Run this workflow on ... +on: + workflow_dispatch: + inputs: + draft: + description: "Mark this as a draft release" + type: choice + options: + - 'false' + - 'true' + force: + description: "Force build even if build already successfully completed for this commit" + type: choice + options: + - 'false' + - 'true' + + workflow_call: + secrets: + DOCKER_USERNAME: + required: true + DOCKER_PASSWORD: + required: true + outputs: + successful: + description: "'True' if maiko build completed successully" + value: ${{ jobs.complete.outputs.build_successful }} + inputs: + draft: + description: "Mark this as a draft release" + required: false + type: string + default: 'false' + force: + description: "Force build even if build already successfully completed for this commit" + required: false + type: string + default: 'false' + +defaults: + run: + shell: bash + +# 2 separate jobs here that can run in parallel +# +# 1. Linux: Build/push a multiplatform Linux Docker image and use results to +# build/push Linux release assets. +# +# 2. MacOs: Build maiko for MacOS (x86_64, aarch64, and universal) then create +# and push release assets. +# + +jobs: + +###################################################################################### + + # Regularize the inputs so they can be referenced the same way whether they are + # the result of a workflow_dispatch or a workflow_call + + inputs: + runs-on: ubuntu-latest + outputs: + draft: ${{ steps.one.outputs.draft }} + force: ${{ steps.one.outputs.force }} + steps: + - id: one + run: > + if [ '${{ toJSON(inputs) }}' = 'null' ]; + then + echo "workflow_dispatch"; + echo "draft=${{ github.event.inputs.draft }}" >> $GITHUB_OUTPUT; + echo "force=${{ github.event.inputs.force }}" >> $GITHUB_OUTPUT; + else + echo "workflow_call"; + echo "draft=${{ inputs.draft }}" >> $GITHUB_OUTPUT; + echo "force=${{ inputs.force }}" >> $GITHUB_OUTPUT; + fi + + + +###################################################################################### + + # Use sentry-action to determine if this release has already been built + # based on the latest commit to the repo + + sentry: + needs: inputs + runs-on: ubuntu-latest + outputs: + release_not_built: ${{ steps.check.outputs.release_not_built }} + + steps: + # Checkout the actions for this repo owner + - name: Checkout Actions + uses: actions/checkout@v3 + with: + repository: ${{ github.repository_owner }}/.github + path: ./Actions_${{ github.sha }} + - run: mv ./Actions_${{ github.sha }}/actions ../actions && rm -rf ./Actions_${{ github.sha }} + + # Check if build already run for this commit + - name: Build already completed? + id: check + continue-on-error: true + uses: ./../actions/check-sentry-action + with: + tag: "release_docker" + +###################################################################################### + + # Linux: build and push multi-platform docker image for Linux + # Use docker images to create and push release assets to github + + linux: + + needs: [inputs, sentry] + if: | + needs.sentry.outputs.release_not_built == 'true' + || needs.inputs.outputs.force == 'true' + + runs-on: ubuntu-latest + + steps: + # Checkout the actions for this repo owner + - name: Checkout Actions + uses: actions/checkout@v3 + with: + repository: ${{ github.repository_owner }}/.github + path: ./Actions_${{ github.sha }} + - run: mv ./Actions_${{ github.sha }}/actions ../actions && rm -rf ./Actions_${{ github.sha }} + + # Checkout the branch + - name: Checkout + uses: actions/checkout@v3 + + # Setup release tag + - name: Setup Release Tag + id: tag + uses: ./../actions/release-tag-action + + # Setup docker environment variables + - name: Setup Docker Environment Variables + id: docker_env + run: | + DOCKER_NAMESPACE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]') + echo "DOCKER_NAMESPACE=${DOCKER_NAMESPACE}" >> ${GITHUB_ENV} + DOCKER_IMAGE=${DOCKER_NAMESPACE}/${{ steps.tag.outputs.repo_name }} + DOCKER_TAGS="${DOCKER_IMAGE}:latest,${DOCKER_IMAGE}:${RELEASE_TAG#*-}" + echo "build_time=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT + echo "docker_tags=${DOCKER_TAGS}" >> $GITHUB_OUTPUT + + # Setup the Docker Machine Emulation environment. + - name: Set up QEMU + uses: docker/setup-qemu-action@master + with: + platforms: linux/amd64,linux/arm64,linux/arm/v7 + + # Setup the Docker Buildx funtion + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@master + + # Login into DockerHub - required to store the created image + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # Do the Docker Build using the Dockerfile in the repository we + # checked out. Push the result to Docker Hub. + # + # NOTE: THE ACTUAL MAIKO BUILD (FOR LINUX) HAPPENS HERE - I.E., IN THE + # DOCKER BUILD CALL. BUILD COMMANDS ARE SPECIFIED IN THE + # Dockerfile, NOT HERE IN THE WORKFLOW. + # + - name: Build Docker Image for Push to Docker Hub + if: ${{ true }} + uses: docker/build-push-action@v4 + with: + builder: ${{ steps.buildx.outputs.name }} + build-args: | + BUILD_DATE=${{ steps.docker_env.outputs.build_time }} + RELEASE_TAG=${{ steps.tag.outputs.release_tag }} + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64,linux/arm/v7 + # Push the result to DockerHub + push: true + tags: ${{ steps.docker_env.outputs.docker_tags }} + + # Redo the Docker Build (hopefully mostly using the cache from the previous build). + # But save the results in a directory under /tmp to be used for creating release tars. + - name: Rebuild Docker Image For Saving Locally + uses: docker/build-push-action@v4 + with: + builder: ${{ steps.buildx.outputs.name }} + build-args: | + BUILD_DATE=${{ steps.docker_env.outputs.build_time }} + RELEASE_TAG=${{ steps.tag.outputs.release_tag }} + context: . + file: ./Dockerfile + platforms: linux/amd64,linux/arm64,linux/arm/v7 + # Put the results out to the local file system + outputs: type=local,dest=/tmp/docker_images + tags: ${{ steps.docker_env.outputs.docker_tags }} + + # Use docker results to create releases for github. + # Docker results are in /tmp/docker_images. One subdir for each platform. + - name: Make release tars for each platform + env: + RELEASE_TAG: ${{ steps.tag.outputs.release_tag }} + run: | + mkdir -p /tmp/release_tars + for OSARCH in "linux.x86_64:linux_amd64" "linux.aarch64:linux_arm64" "linux.armv7l:linux_arm_v7" ; \ + do \ + pushd /tmp/docker_images/${OSARCH##*:}/usr/local/interlisp >/dev/null ; \ + /usr/bin/tar -c -z \ + -f /tmp/release_tars/${RELEASE_TAG}-${OSARCH%%:*}.tgz \ + maiko/bin/osversion \ + maiko/bin/machinetype \ + maiko/bin/config.guess \ + maiko/bin/config.sub \ + maiko/${OSARCH%%:*}/lde* \ + ; \ + popd >/dev/null ; \ + done + + # Push Release to github + - name: Push the release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + artifacts: + /tmp/release_tars/${{ steps.tag.outputs.release_tag }}-linux.x86_64.tgz, + /tmp/release_tars/${{ steps.tag.outputs.release_tag }}-linux.aarch64.tgz, + /tmp/release_tars/${{ steps.tag.outputs.release_tag }}-linux.armv7l.tgz + tag: ${{ steps.tag.outputs.release_tag }} + draft: ${{ needs.inputs.outputs.draft }} + token: ${{ secrets.GITHUB_TOKEN }} + + +###################################################################################### + + # MacOS: build for MacOS (x86_64, aarch64, universal) and use results to + # create and push release assets to github + macos: + + needs: [inputs, sentry] + if: | + needs.sentry.outputs.release_not_built == 'true' + || needs.inputs.outputs.force == 'true' + + runs-on: macos-latest + + steps: + + # Checkout the branch + - name: Checkout + uses: actions/checkout@v3 + + # Checkout the actions for this repo owner + - name: Checkout Actions + uses: actions/checkout@v3 + with: + repository: ${{ github.repository_owner }}/.github + path: ./Actions_${{ github.sha }} + - run: mv ./Actions_${{ github.sha }}/actions ../actions && rm -rf ./Actions_${{ github.sha }} + + # Setup release tag + - name: Setup Release Tag + id: tag + uses: ./../actions/release-tag-action + + # Uninstall exisitng X11 stuff preconfigured on runner then install correct X11 dependencies + - name: Unistall X components already on the runner + run: | + brew uninstall --ignore-dependencies libxft + brew uninstall --ignore-dependencies libxrender + brew uninstall --ignore-dependencies libxext + brew uninstall --ignore-dependencies libx11 + brew uninstall --ignore-dependencies xorgproto + brew uninstall --ignore-dependencies libxdmcp + brew uninstall --ignore-dependencies libxau + + - name: Install X11 dependencies on MacOS + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release download XQuartz-2.8.5 --repo XQuartz/XQuartz --pattern XQuartz-2.8.5.pkg + sudo installer -pkg ./XQuartz-2.8.5.pkg -target / + + # Install SDL dependencies + - name: Install SDL2 dependencies on MacOS + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release download release-2.26.5 --repo libsdl-org/SDL --pattern SDL2-2.26.5.dmg + hdiutil attach SDL2-2.26.5.dmg + sudo ditto /Volumes/SDL2/SDL2.framework /Library/Frameworks/SDL2.framework + hdiutil detach /Volumes/SDL2/ + + # Build maiko + - name: Build ldeinit + working-directory: ./bin + run: | + export LDEARCH=x86_64-apple-darwin + ./makeright init + export LDEARCH=aarch64-apple-darwin + ./makeright init + mkdir -p ../darwin.universal + exe=ldeinit + lipo -create \ + -arch arm64 ../darwin.aarch64/${exe} \ + -arch x86_64 ../darwin.x86_64/${exe} \ + -output ../darwin.universal/${exe} + + - name: Build lde, ldex, & ldesdl + run: | + mkdir build + cd build + # -DCMAKE_OSX_DEPLOYMENT_TARGET=10.12 + cmake .. \ + -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" \ + -DMAIKO_DISPLAY_SDL=ON \ + -DMAIKO_DISPLAY_X11=ON \ + -DCMAKE_BUILD_TYPE=Release + cmake --build . --config Release + for exe in lde ldex ldesdl + do + lipo ${exe} -output ../darwin.x86_64/${exe} -extract x86_64 + lipo ${exe} -output ../darwin.aarch64/${exe} -extract arm64 + cp -p ${exe} ../darwin.universal/${exe} + done + + # Create release tar for github. + - name: Make release tar(s) + env: + RELEASE_TAG: ${{ steps.tag.outputs.release_tag }} + run: | + mkdir -p /tmp/release_tars + cd ${GITHUB_WORKSPACE}/../ + for arch in x86_64 aarch64 universal + do + tar -c -z \ + -f /tmp/release_tars/${RELEASE_TAG}-darwin.${arch}.tgz \ + maiko/bin/osversion \ + maiko/bin/machinetype \ + maiko/bin/config.guess \ + maiko/bin/config.sub \ + maiko/darwin.${arch}/lde* + done + + # Push Release + - name: Push the release + uses: ncipollo/release-action@v1 + with: + allowUpdates: true + artifacts: + /tmp/release_tars/${{ steps.tag.outputs.release_tag }}-darwin.x86_64.tgz, + /tmp/release_tars/${{ steps.tag.outputs.release_tag }}-darwin.aarch64.tgz, + /tmp/release_tars/${{ steps.tag.outputs.release_tag }}-darwin.universal.tgz + tag: ${{ steps.tag.outputs.release_tag }} + draft: ${{ needs.inputs.outputs.draft }} + token: ${{ secrets.GITHUB_TOKEN }} + + + +###################################################################################### + + # Use set-sentry-action to determine set the sentry that says this release has + # been successfully built + + complete: + + runs-on: ubuntu-latest + + outputs: + build_successful: ${{ steps.output.outputs.build_successful }} + + needs: [inputs, sentry, linux, macos] + + steps: + # Checkout the actions for this repo owner + - name: Checkout Actions + uses: actions/checkout@v3 + with: + repository: ${{ github.repository_owner }}/.github + path: ./Actions_${{ github.sha }} + - run: mv ./Actions_${{ github.sha }}/actions ../actions && rm -rf ./Actions_${{ github.sha }} + + # Set sentry + - name: Is build for this commit already completed? + id: set + uses: ./../actions/set-sentry-action + with: + tag: "release_docker" + + - name: Output + id: output + run: | + echo "build_successful=true" >> $GITHUB_OUTPUT + + +######################################################################################