diff --git a/.github/workflows/test-build.yml b/.github/workflows/_build.yml similarity index 58% rename from .github/workflows/test-build.yml rename to .github/workflows/_build.yml index e8e723b..75a1e10 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/_build.yml @@ -1,117 +1,138 @@ --- -name: Test Build +# Requires _prepare.yml re-usable workflow to have run. +name: Build for macOS on: - workflow_dispatch: + workflow_call: inputs: - gitRef: - description: "Emacs git ref to build" + artifact_prefix: + description: Artifact prefix + type: string + required: false + os: + description: GitHub Actions runner OS + type: string required: true - default: "master" - emacsBuilderGitRef: - description: "Git ref to checkout of build-emacs-for-macos" + git_ref: + description: Git ref to build + type: string required: true - default: "master" - testBuildName: + git_sha: + description: Override git SHA to build + type: string + required: false + test_build_name: description: "Test build name" - required: true - testReleaseType: + type: string + required: false + test_release_type: description: "prerelease or draft" - required: true + type: string + required: false default: "prerelease" - extraPlanArgs: - description: "Extra plan args" - required: false - default: "" - extraCheckArgs: - description: "Extra check args" - required: false - default: "" - extraBuildArgs: - description: "Extra build args" - required: false - default: "--native-full-aot --no-relink-eln-files" - extraPackageArgs: - description: "Extra package args" - required: false - default: "" - extraReleaseArgs: - description: "Extra release args" - required: false - default: "" + secrets: + APPLE_DEVELOPER_CERTIFICATE_P12_BASE64: + description: Base64 encoded Apple Developer Certificate + required: true + APPLE_DEVELOPER_CERTIFICATE_PASSWORD: + description: Password for Apple Developer Certificate + required: true + KEYCHAIN_PASSWORD: + description: Password to use for temporary local keychain on runner + required: true + AC_USERNAME: + description: Apple Connect Username + required: true + AC_PASSWORD: + description: Apple Connect Password + required: true + AC_PROVIDER: + description: Apple Connect Provider + required: true + AC_SIGN_IDENTITY: + description: Apple Connect Signing Identify + required: true + TAP_REPO_TOKEN: + description: Homebrew Tap Token + required: true jobs: - plan: - runs-on: macos-10.15 + prepare: + runs-on: ${{ inputs.os }} outputs: - check: ${{ steps.check.outcome }} builder_sha: ${{ steps.builder_sha.outputs.sha }} + emacs_sha_override: ${{ steps.emacs_sha.outputs.sha }} + test_plan_args: ${{ steps.test_plan_args.outputs.args }} steps: - - name: Checkout build-emacs-for-macos repo - uses: actions/checkout@v2 + - name: Download emacs-builder git SHA artifact + uses: actions/download-artifact@v2 with: - repository: jimeh/build-emacs-for-macos - ref: ${{ github.event.inputs.emacsBuilderGitRef }} - path: builder + name: emacs-builder-git-sha + path: ./ - name: Store builder Git SHA id: builder_sha - run: echo "::set-output name=sha::$(git rev-parse HEAD)" - working-directory: builder - - uses: actions/setup-go@v2 + run: >- + echo "::set-output name=sha::$(cat emacs-builder-git-sha.txt)" + - name: Prepare plan test args + id: test_plan_args + if: ${{ inputs.test_build_name != '' }} + run: >- + echo "::set-output name=args::--test-build '${{ inputs.test_build_name }}' --test-release-type '${{ inputs.test_release_type }}'" + - name: Set git SHA override + id: emacs_sha + if: ${{ inputs.git_sha != '' }} + run: >- + echo "::set-output name=sha::--sha '${{ inputs.git_sha }}'" + + plan: + needs: [prepare] + runs-on: ${{ inputs.os }} + outputs: + check: ${{ steps.check.outputs.result }} + steps: + - name: Download pre-built emacs-builder artifact + uses: actions/download-artifact@v2 with: - go-version: 1.16 - - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('builder/**/go.sum') }} - restore-keys: ${{ runner.os }}-go- - - name: Pre-build emacs-builder tool - run: make build - working-directory: builder + name: emacs-builder + path: bin + - name: Ensure emacs-builder is executable + run: chmod +x bin/emacs-builder - name: Plan build run: >- - builder/bin/emacs-builder -l debug plan - --output build-plan.yml + bin/emacs-builder -l debug plan --output build-plan.yml --output-dir '${{ github.workspace }}/builds' - --test-build '${{ github.event.inputs.testBuildName }}' - --test-release-type '${{ github.event.inputs.testReleaseType }}' - ${{ github.event.inputs.extraPlanArgs }} - '${{ github.event.inputs.gitRef }}' + ${{ needs.prepare.outputs.test_plan_args }} + ${{ needs.prepare.outputs.emacs_sha_override }} + '${{ inputs.git_ref }}' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Show plan run: cat build-plan.yml - - name: Check if planned release and asset already exist - id: check - continue-on-error: true - run: >- - builder/bin/emacs-builder -l debug release --plan build-plan.yml check - ${{ github.event.inputs.extraCheckArgs }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload pre-built emacs-builder artifact - uses: actions/upload-artifact@v2 - with: - name: emacs-builder - path: builder/bin/emacs-builder - if-no-files-found: error - name: Upload build-plan.yml artifact uses: actions/upload-artifact@v2 with: - name: build-plan.yml + name: ${{ inputs.artifact_prefix }}build-plan.yml path: build-plan.yml if-no-files-found: error + - name: Check if planned release and asset already exist + id: check + continue-on-error: true + run: | + RESULT="$((bin/emacs-builder -l debug release --plan build-plan.yml check && echo 'ok') || echo 'fail')" + echo "::set-output name=result::$RESULT" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} build: - runs-on: macos-10.15 - needs: [plan] + runs-on: ${{ inputs.os }} + needs: [prepare, plan] # Only run if check for existing release and asset failed. - if: ${{ needs.plan.outputs.check == 'failure' }} + if: ${{ needs.plan.outputs.check == 'fail' }} steps: - name: Checkout build-emacs-for-macos repo uses: actions/checkout@v2 with: repository: jimeh/build-emacs-for-macos - ref: ${{ needs.plan.outputs.builder_sha }} + ref: ${{ needs.prepare.outputs.builder_sha }} path: builder - uses: ruby/setup-ruby@v1 with: @@ -122,34 +143,30 @@ jobs: - name: Download build-plan.yml artifact uses: actions/download-artifact@v2 with: - name: build-plan.yml + name: ${{ inputs.artifact_prefix }}build-plan.yml path: ./ - name: Build Emacs run: >- ./builder/build-emacs-for-macos --plan build-plan.yml - ${{ github.event.inputs.extraBuildArgs }} + --no-relink-eln-files --native-full-aot env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload unsigned app artifact uses: actions/upload-artifact@v2 with: - name: unsigned-app + name: ${{ inputs.artifact_prefix }}unsigned-app path: builds/*.tbz if-no-files-found: error package: - runs-on: macos-10.15 - needs: [build] + runs-on: ${{ inputs.os }} + needs: [prepare, plan, build] + # Only run if check for existing release and asset failed. steps: - - name: Download unsigned app artifact - uses: actions/download-artifact@v2 - with: - name: unsigned-app - path: builds - - name: Extract unsigned app archive + - name: Install dependencies run: | - find * -name '*.tbz' -exec tar xvjf "{}" \; - working-directory: builds + brew install python + $(command -v pip3 || command -v pip) install --upgrade dmgbuild - name: Download pre-built emacs-builder artifact uses: actions/download-artifact@v2 with: @@ -160,8 +177,17 @@ jobs: - name: Download build-plan.yml artifact uses: actions/download-artifact@v2 with: - name: build-plan.yml + name: ${{ inputs.artifact_prefix }}build-plan.yml path: ./ + - name: Download unsigned app artifact + uses: actions/download-artifact@v2 + with: + name: ${{ inputs.artifact_prefix }}unsigned-app + path: builds + - name: Extract unsigned app archive + run: | + find * -name '*.tbz' -exec tar xvjf "{}" \; + working-directory: builds - name: Install the Apple signing certificate run: | # create variables @@ -187,7 +213,7 @@ jobs: - name: Sign, package and notarize build run: >- bin/emacs-builder -l debug package -v --plan build-plan.yml - --sign ${{ github.event.inputs.extraPackageArgs }} + --sign --remove-source-dir env: AC_USERNAME: ${{ secrets.AC_USERNAME }} AC_PASSWORD: ${{ secrets.AC_PASSWORD }} @@ -196,7 +222,7 @@ jobs: - name: Upload disk image artifacts uses: actions/upload-artifact@v2 with: - name: signed-dmg + name: dmg path: | builds/*.dmg builds/*.sha* @@ -205,31 +231,3 @@ jobs: if: ${{ always() }} run: | security delete-keychain "$RUNNER_TEMP/app-signing.keychain-db" - - release: - runs-on: macos-10.15 - needs: [package] - steps: - - name: Download pre-built emacs-builder artifact - uses: actions/download-artifact@v2 - with: - name: emacs-builder - path: bin - - name: Ensure emacs-builder is executable - run: chmod +x bin/emacs-builder - - name: Download build-plan.yml artifact - uses: actions/download-artifact@v2 - with: - name: build-plan.yml - path: ./ - - name: Download disk image artifact - uses: actions/download-artifact@v2 - with: - name: signed-dmg - path: builds - - name: Publish disk image to GitHub Release - run: >- - bin/emacs-builder -l debug release --plan build-plan.yml publish - ${{ github.event.inputs.extraReleaseArgs }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/_prepare.yml b/.github/workflows/_prepare.yml new file mode 100644 index 0000000..bae5813 --- /dev/null +++ b/.github/workflows/_prepare.yml @@ -0,0 +1,53 @@ +--- +name: Prepare +on: + workflow_call: + inputs: + builder_ref: + description: Git ref to checkout of build-emacs-for-macos + required: true + type: string + secrets: + TAP_REPO_TOKEN: + description: Personal Access Token for Homebrew Tap repo + required: true + +jobs: + emacs-builder: + # Use oldest version of macOS to ensure emacs-bulder binary is compatible + # with later versions of macOS. + runs-on: macos-10.15 + steps: + - name: Checkout build-emacs-for-macos repo + uses: actions/checkout@v2 + with: + repository: jimeh/build-emacs-for-macos + ref: ${{ inputs.builder_ref }} + path: builder + - name: Store builder Git SHA + run: | + git rev-parse HEAD > emacs-builder-git-sha.txt + working-directory: builder + - name: Upload builder git SHA artifact + uses: actions/upload-artifact@v2 + with: + name: emacs-builder-git-sha + path: builder/emacs-builder-git-sha.txt + if-no-files-found: error + - uses: actions/setup-go@v2 + with: + go-version: 1.16 + - uses: actions/cache@v2 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('builder/**/go.sum') }} + restore-keys: ${{ runner.os }}-go- + - name: Build emacs-builder tool + run: make build + working-directory: builder + - name: Upload emacs-builder artifact + uses: actions/upload-artifact@v2 + with: + name: emacs-builder + path: builder/bin/emacs-builder + if-no-files-found: error diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml new file mode 100644 index 0000000..3641b30 --- /dev/null +++ b/.github/workflows/_release.yml @@ -0,0 +1,52 @@ +--- +# Requires _prepare.yml and _build.yml re-usable workflows to have run. +name: Release +on: + workflow_call: + inputs: + plan_artifact: + description: Name of artifact containing a emacs-builder plan.yml file + type: string + required: true + dmg_artifact: + description: Name of artifact containing a *.dmg files to release + type: string + required: true + secrets: + TAP_REPO_TOKEN: + description: Personal Access Token for Homebrew Tap repo + required: true + +jobs: + github: + runs-on: macos-11 + steps: + - name: Download pre-built emacs-builder artifact + uses: actions/download-artifact@v2 + with: + name: emacs-builder + path: bin + - name: Ensure emacs-builder is executable + run: chmod +x bin/emacs-builder + - name: Download build-plan.yml artifact + uses: actions/download-artifact@v2 + with: + name: ${{ inputs.plan_artifact }} + path: ./ + - name: Download disk image artifacts + uses: actions/download-artifact@v2 + with: + name: ${{ inputs.dmg_artifact }} + path: builds + - name: Publish disk images to a GitHub Release + run: >- + bin/emacs-builder -l debug release --plan build-plan.yml publish + $(find builds -name '*.dmg' -or -name '*.sha256') + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Trigger update casks workflow in homebrew tap + if: ${{ inputs.testBuildName == '' }} + run: >- + gh workflow run --repo jimeh/homebrew-emacs-builds update-casks.yml + env: + GITHUB_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81f6fcc..dc64193 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,206 +1,67 @@ --- name: Build on: - schedule: - - cron: "0 0 * * *" workflow_dispatch: inputs: - gitRef: - description: "Emacs git ref to build" + git_ref: + description: Emacs git ref to build required: true default: "master" - extraPlanArgs: - description: "Extra plan args" + git_sha: + description: Override Emacs git commit SHA to build + required: false + builder_ref: + description: "Git ref to checkout of build-emacs-for-macos" + required: true + default: "master" + os: + description: 'Runner OS ("macos-10.15" or "macos-11")' + required: true + default: "macos-10.15" + test_build_name: + description: "Test build name" required: false default: "" - extraCheckArgs: - description: "Extra check args" - required: false - default: "" - extraBuildArgs: - description: "Extra build args" - required: false - default: "" - extraPackageArgs: - description: "Extra package args" - required: false - default: "" - extraReleaseArgs: - description: "Extra release args" + test_release_type: + description: "prerelease or draft" required: false default: "" jobs: - plan: - runs-on: macos-10.15 - outputs: - check: "${{ steps.check.outcome }}" - steps: - - name: Checkout build-emacs-for-macos repo - uses: actions/checkout@v2 - with: - repository: jimeh/build-emacs-for-macos - ref: "v0.6.15" - path: builder - - uses: actions/setup-go@v2 - with: - go-version: 1.16 - - uses: actions/cache@v2 - id: builder-cache - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('builder/**/go.sum') }} - restore-keys: ${{ runner.os }}-go- - - name: Pre-build emacs-builder tool - run: make build - working-directory: builder - - name: Plan build - run: >- - builder/bin/emacs-builder -l debug plan - --output build-plan.yml - --output-dir '${{ github.workspace }}/builds' - ${{ github.event.inputs.extraPlanArgs }} - '${{ github.event.inputs.gitRef }}' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Show plan - run: cat build-plan.yml - - name: Check if planned release and asset already exist - id: check - continue-on-error: true - run: >- - builder/bin/emacs-builder -l debug release --plan build-plan.yml check - ${{ github.event.inputs.extraCheckArgs }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Upload pre-built emacs-builder artifact - uses: actions/upload-artifact@v2 - with: - name: emacs-builder - path: builder/bin/emacs-builder - if-no-files-found: error - - name: Upload build-plan.yml artifact - uses: actions/upload-artifact@v2 - with: - name: build-plan.yml - path: build-plan.yml - if-no-files-found: error + prepare: + name: Prepare + uses: jimeh/emacs-builds/.github/workflows/_prepare.yml@main + with: + builder_ref: ${{ github.event.inputs.builder_ref }} + secrets: + TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} build: - runs-on: macos-10.15 - needs: [plan] - # Only run if check for existing release and asset failed. - if: ${{ needs.plan.outputs.check == 'failure' }} - steps: - - name: Checkout build-emacs-for-macos repo - uses: actions/checkout@v2 - with: - repository: jimeh/build-emacs-for-macos - ref: "v0.6.15" - path: builder - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - - name: Install dependencies - run: make bootstrap-ci - working-directory: builder - - name: Download pre-built emacs-builder artifact - uses: actions/download-artifact@v2 - id: builder - with: - name: emacs-builder - path: bin - - name: Ensure emacs-builder is executable - run: chmod +x bin/emacs-builder - - name: Download build-plan.yml artifact - uses: actions/download-artifact@v2 - id: plan - with: - name: build-plan.yml - path: ./ - - name: Build Emacs - run: >- - ./builder/build-emacs-for-macos --plan build-plan.yml - --no-relink-eln-files --native-full-aot --no-archive - ${{ github.event.inputs.extraBuildArgs }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Install the Apple signing certificate - run: | - # create variables - CERTIFICATE_PATH="$RUNNER_TEMP/build_certificate.p12" - KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db" - - # import certificate and provisioning profile from secrets - echo -n "$CERT_BASE64" | base64 --decode --output "$CERTIFICATE_PATH" - - # create temporary keychain - security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" - security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" - - # import certificate to keychain - security import "$CERTIFICATE_PATH" -P "$CERT_PASSWORD" -A \ - -t cert -f pkcs12 -k "$KEYCHAIN_PATH" - security list-keychain -d user -s "$KEYCHAIN_PATH" - env: - CERT_BASE64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} - CERT_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} - KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - - name: Sign, package and notarize build - run: >- - bin/emacs-builder -l debug package -v --plan build-plan.yml - --sign --remove-source-dir - ${{ github.event.inputs.extraPackageArgs }} - env: - AC_USERNAME: ${{ secrets.AC_USERNAME }} - AC_PASSWORD: ${{ secrets.AC_PASSWORD }} - AC_PROVIDER: ${{ secrets.AC_PROVIDER }} - AC_SIGN_IDENTITY: ${{ secrets.AC_SIGN_IDENTITY }} - - name: Upload disk image artifacts - uses: actions/upload-artifact@v2 - with: - name: dmg - path: | - builds/*.dmg - builds/*.sha* - if-no-files-found: error - - name: Clean up keychain used for signing certificate - if: ${{ always() }} - run: | - security delete-keychain "$RUNNER_TEMP/app-signing.keychain-db" + name: Build + needs: [prepare] + uses: jimeh/emacs-builds/.github/workflows/_build.yml@main + with: + os: macos-10.15 + git_ref: ${{ github.event.inputs.git_ref }} + git_sha: ${{ github.event.inputs.git_sha }} + test_build_name: ${{ github.event.inputs.test_build_name }} + test_release_type: ${{ github.event.inputs.test_release_type }} + secrets: + APPLE_DEVELOPER_CERTIFICATE_P12_BASE64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} + APPLE_DEVELOPER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + AC_USERNAME: ${{ secrets.AC_USERNAME }} + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + AC_PROVIDER: ${{ secrets.AC_PROVIDER }} + AC_SIGN_IDENTITY: ${{ secrets.AC_SIGN_IDENTITY }} + TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} release: - runs-on: macos-10.15 + name: Release needs: [build] - steps: - - name: Download pre-built emacs-builder artifact - uses: actions/download-artifact@v2 - id: builder - with: - name: emacs-builder - path: bin - - name: Ensure emacs-builder is executable - run: chmod +x bin/emacs-builder - - name: Download build-plan.yml artifact - uses: actions/download-artifact@v2 - id: plan - with: - name: build-plan.yml - path: ./ - - name: Download disk image artifact - uses: actions/download-artifact@v2 - with: - name: dmg - path: builds - - name: Publish disk image to a GitHub Release - run: >- - bin/emacs-builder -l debug release --plan build-plan.yml publish - ${{ github.event.inputs.extraReleaseArgs }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Trigger update casks workflow in homebrew tap - run: >- - gh workflow run --repo jimeh/homebrew-emacs-builds update-casks.yml - env: - GITHUB_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} + uses: jimeh/emacs-builds/.github/workflows/_release.yml@main + with: + plan_artifact: big-sur_build-plan.yml + dmg_artifact: dmg + secrets: + TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} diff --git a/.github/workflows/nightly-master.yml b/.github/workflows/nightly-master.yml new file mode 100644 index 0000000..268289d --- /dev/null +++ b/.github/workflows/nightly-master.yml @@ -0,0 +1,48 @@ +--- +name: Nightly (master) +on: + push: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + inputs: + git_sha: + description: Override Emacs git commit SHA to build + required: false + +jobs: + prepare: + name: Prepare + uses: jimeh/emacs-builds/.github/workflows/_prepare.yml@main + with: + builder_ref: v0.6.17 + secrets: + TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} + + build: + name: Build + needs: [prepare] + uses: jimeh/emacs-builds/.github/workflows/_build.yml@main + with: + os: macos-10.15 + git_ref: master + git_sha: ${{ github.event.inputs.git_sha }} + secrets: + APPLE_DEVELOPER_CERTIFICATE_P12_BASE64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} + APPLE_DEVELOPER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + AC_USERNAME: ${{ secrets.AC_USERNAME }} + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + AC_PROVIDER: ${{ secrets.AC_PROVIDER }} + AC_SIGN_IDENTITY: ${{ secrets.AC_SIGN_IDENTITY }} + TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }} + + release: + name: Release + needs: [build] + uses: jimeh/emacs-builds/.github/workflows/_release.yml@main + with: + plan_artifact: catalina_build-plan.yml + dmg_artifact: dmg + secrets: + TAP_REPO_TOKEN: ${{ secrets.TAP_REPO_TOKEN }}