-
Notifications
You must be signed in to change notification settings - Fork 16
Publish subsequent internal releases right after building #2306
Changes from all commits
6cf9b89
1ff9fda
6995a7d
284dd63
1b8dbfa
e7cac3d
c0de433
1ffa2f3
c6e8754
145613d
b47e251
a603ca6
dfa128b
d8bb58f
bfdd0df
25f4020
41f1455
faad4c4
d694407
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| data: | ||
| name: Run Publish DMG Release GitHub Actions workflow | ||
| assignee: "${ASSIGNEE_ID}" | ||
| html_notes: | | ||
| <body> | ||
| <h1>Using GH CLI</h1> | ||
| Run the following command: | ||
| <code>gh workflow run publish_dmg_release.yml --ref ${BRANCH} -f asana-task-url=${ASANA_TASK_URL} -f tag=${TAG} -f release-type=internal</code> | ||
| <h1>Using GitHub web UI</h1> | ||
| <ol> | ||
| <li>Open <a href='https://github.com/duckduckgo/macos-browser/actions/workflows/publish_dmg_release.yml'>Publish DMG Release workflow page</a>.</li> | ||
| <li>Click "Run Workflow" and fill in the form as follows: | ||
| <ul> | ||
| <li><b>Branch</b> <code>${BRANCH}</code></li> | ||
| <li><b>Asana release task URL</b> <code>${ASANA_TASK_URL}</code></li> | ||
| <li><b>Tag to publish</b> <code>${TAG}</code></li> | ||
| <li><b>Release Type</b> <code>internal</code></li> | ||
|
Comment on lines
+16
to
+19
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Parametrized instructions on how to set up a workflow run 👍 |
||
| </ul></li> | ||
| </ol> | ||
| The GitHub Action workflow does the following: | ||
| <ul> | ||
| <li>Fetches the release DMG from staticcdn.duckduckgo.com</li> | ||
| <li>Extracts release notes from the Asana task description</li> | ||
| <li>Runs <code>appcastManager</code> to generate the new appcast2.xml file</li> | ||
| <li>Stores the diff against previous version and the copy of the old appcast2.xml file</li> | ||
| <li>Uploads new appcast, DMG and binary delta files to S3</li> | ||
| <li>On success, creates a task for the release DRI to validate that "Check for Updates" works, with instructions on how to revert that change if "Check for Updates" is broken.</li> | ||
| <li>On failure, creates a task for the release DRI with manual instructions on generating the appcast and uploading to S3.</li> | ||
| </ul> | ||
| Complete this task when ready and proceed with testing the build. If GitHub Actions is unavailable, you'll find manual instructions in the <em>Run Publish DMG Release GitHub Actions workflow</em> subtask of <em>Make Internal Release</em> task. | ||
| 🔗 Workflow URL: <a href='${WORKFLOW_URL}'>${WORKFLOW_URL}</a>. | ||
| </body> | ||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -129,6 +129,20 @@ jobs: | |
| branch: ${{ github.ref_name }} | ||
| base-branch: ${{ github.event.inputs.base-branch || 'main' }} | ||
| prerelease: true | ||
| internal-release-bump: true | ||
| secrets: | ||
| ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }} | ||
| GHA_ELEVATED_PERMISSIONS_TOKEN: ${{ secrets.GHA_ELEVATED_PERMISSIONS_TOKEN }} | ||
|
|
||
| publish_release: | ||
| name: Publish DMG Release | ||
| needs: [ tag_and_merge ] | ||
| uses: ./.github/workflows/publish_dmg_release.yml | ||
| with: | ||
| asana-task-url: ${{ github.event.inputs.asana-task-url }} | ||
| secrets: | ||
| ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }} | ||
| AWS_ACCESS_KEY_ID_RELEASE_S3: ${{ secrets.AWS_ACCESS_KEY_ID_RELEASE_S3 }} | ||
| AWS_SECRET_ACCESS_KEY_RELEASE_S3: ${{ secrets.AWS_SECRET_ACCESS_KEY_RELEASE_S3 }} | ||
| GHA_ELEVATED_PERMISSIONS_TOKEN: ${{ secrets.GHA_ELEVATED_PERMISSIONS_TOKEN }} | ||
| SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }} | ||
|
Comment on lines
+137
to
+148
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the main change here :) every subsequent internal release is automatically published to Sparkle internal channel. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,16 +19,34 @@ on: | |
| - internal | ||
| - public | ||
| - hotfix | ||
| workflow_call: | ||
| inputs: | ||
| asana-task-url: | ||
| description: "Asana release task URL" | ||
| required: true | ||
| type: string | ||
| secrets: | ||
| ASANA_ACCESS_TOKEN: | ||
| required: true | ||
| AWS_ACCESS_KEY_ID_RELEASE_S3: | ||
| required: true | ||
| AWS_SECRET_ACCESS_KEY_RELEASE_S3: | ||
| required: true | ||
| GHA_ELEVATED_PERMISSIONS_TOKEN: | ||
| required: true | ||
| SPARKLE_PRIVATE_KEY: | ||
| required: true | ||
|
|
||
| jobs: | ||
|
|
||
| # This is only run for public and hotfix releases | ||
| # This is only run for public and hotfix releases, so only when it's triggered manually. | ||
| # Internal release has been tagged as part of code_freeze or bump_interal_release workflows | ||
| tag-public-release: | ||
|
|
||
| name: Tag public release | ||
|
|
||
| if: ${{ github.event.inputs.release-type != 'internal' }} | ||
| # Run if release-type is provided (not empty) an is not internal | ||
| if: contains(github.event.inputs.release-type, '') == false && github.event.inputs.release-type != 'internal' | ||
|
|
||
| uses: ./.github/workflows/tag_release.yml | ||
| with: | ||
|
|
@@ -43,6 +61,10 @@ jobs: | |
|
|
||
| name: Publish a release to Sparkle | ||
|
|
||
| env: | ||
| RELEASE_TYPE: ${{ github.event.inputs.release-type || 'internal' }} | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RELEASE_TYPE is used in a few places in this workflow so I extracted it to the job-level env. |
||
| SPARKLE_DIR: ${{ github.workspace }}/sparkle-updates | ||
|
|
||
| needs: [tag-public-release] | ||
|
|
||
| # Allow to run even if the tag-public-release job was skipped (e.g. for internal releases) | ||
|
|
@@ -52,23 +74,34 @@ jobs: | |
| runs-on: macos-13-xlarge | ||
| timeout-minutes: 10 | ||
|
|
||
| env: | ||
| SPARKLE_DIR: ${{ github.workspace }}/sparkle-updates | ||
|
|
||
| steps: | ||
|
|
||
| - name: Download tag artifact | ||
| id: download-tag | ||
| continue-on-error: true | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: tag | ||
| path: .github | ||
|
|
||
| - name: Set tag variable | ||
| run: | | ||
| if [[ "${{ steps.download-tag.outcome }}" == 'success' ]]; then | ||
| echo "TAG=$(<.github/tag)" >> $GITHUB_ENV | ||
| else | ||
| echo "TAG=${{ github.event.inputs.tag }}" >> $GITHUB_ENV | ||
| fi | ||
|
|
||
| - name: Verify the tag | ||
| id: verify-tag | ||
| env: | ||
| tag: ${{ github.event.inputs.tag }} | ||
| run: | | ||
| tag_regex='^[0-9]+\.[0-9]+\.[0-9]+-[0-9]+$' | ||
|
|
||
| if [[ ! "$tag" =~ $tag_regex ]]; then | ||
| echo "::error::The provided tag ($tag) has incorrect format (attempted to match ${tag_regex})." | ||
| if [[ ! "$TAG" =~ $tag_regex ]]; then | ||
| echo "::error::The provided tag ($TAG) has incorrect format (attempted to match ${tag_regex})." | ||
| exit 1 | ||
| fi | ||
| echo "release-version=${tag//-/.}" >> $GITHUB_OUTPUT | ||
| echo "release-version=${TAG//-/.}" >> $GITHUB_OUTPUT | ||
|
|
||
| - name: Check out the code | ||
| uses: actions/checkout@v4 | ||
|
|
@@ -87,12 +120,11 @@ jobs: | |
|
|
||
| - name: Fetch DMG | ||
| id: fetch-dmg | ||
| if: ${{ github.event.inputs.release-type != 'public' }} | ||
| env: | ||
| DMG_NAME: duckduckgo-${{ steps.verify-tag.outputs.release-version }}.dmg | ||
| run: | | ||
| # Public release doesn't need fetching a DMG (it's already uploaded to S3) | ||
| if [[ "${{ github.event.inputs.release-type }}" != 'public' ]]; then | ||
| if [[ "${RELEASE_TYPE}" != 'public' ]]; then | ||
| DMG_URL="${{ vars.DMG_URL_ROOT }}${DMG_NAME}" | ||
| curl -fLSs -o "$DMG_NAME" "$DMG_URL" | ||
| fi | ||
|
|
@@ -121,7 +153,6 @@ jobs: | |
| env: | ||
| DMG_PATH: ${{ steps.fetch-dmg.outputs.dmg-path }} | ||
| SPARKLE_PRIVATE_KEY: ${{ secrets.SPARKLE_PRIVATE_KEY }} | ||
| RELEASE_TYPE: ${{ github.event.inputs.release-type }} | ||
| VERSION: ${{ steps.verify-tag.outputs.release-version }} | ||
| run: | | ||
| echo -n "$SPARKLE_PRIVATE_KEY" > sparkle_private_key | ||
|
|
@@ -169,7 +200,6 @@ jobs: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID_RELEASE_S3 }} | ||
| AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY_RELEASE_S3 }} | ||
| AWS_DEFAULT_REGION: ${{ vars.AWS_DEFAULT_REGION }} | ||
| RELEASE_TYPE: ${{ github.event.inputs.release-type }} | ||
| VERSION: ${{ steps.verify-tag.outputs.release-version }} | ||
| run: | | ||
| # Back up existing appcast2.xml | ||
|
|
@@ -192,7 +222,7 @@ jobs: | |
|
|
||
| - name: Update Asana for the release | ||
| id: update-asana | ||
| if: ${{ github.event.inputs.release-type != 'internal' }} | ||
| if: ${{ env.RELEASE_TYPE != 'internal' }} | ||
| continue-on-error: true | ||
| env: | ||
| ASANA_ACCESS_TOKEN: ${{ secrets.ASANA_ACCESS_TOKEN }} | ||
|
|
@@ -217,15 +247,12 @@ jobs: | |
| echo "RELEASE_BUCKET_NAME=${{ vars.RELEASE_BUCKET_NAME }}" >> $GITHUB_ENV | ||
| echo "RELEASE_BUCKET_PREFIX=${{ vars.RELEASE_BUCKET_PREFIX }}" >> $GITHUB_ENV | ||
| echo "RELEASE_TASK_ID=${{ steps.task-id.outputs.task-id }}" >> $GITHUB_ENV | ||
| echo "TAG=${{ github.event.inputs.tag }}" >> $GITHUB_ENV | ||
| echo "VERSION=${{ steps.verify-tag.outputs.release-version }}" >> $GITHUB_ENV | ||
| echo "WORKFLOW_URL=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> $GITHUB_ENV | ||
|
|
||
| - name: Set up Asana templates | ||
| if: always() | ||
| id: asana-templates | ||
| env: | ||
| RELEASE_TYPE: ${{ github.event.inputs.release-type }} | ||
| run: | | ||
| if [[ ${{ steps.upload.outcome }} == "success" ]]; then | ||
| if [[ "${RELEASE_TYPE}" == "internal" ]]; then | ||
|
|
@@ -264,7 +291,7 @@ jobs: | |
|
|
||
| - name: Create Asana task to announce the release | ||
| id: create-announcement-task | ||
| if: ${{ github.event.inputs.release-type != 'internal' }} | ||
| if: ${{ env.RELEASE_TYPE != 'internal' }} | ||
| uses: ./.github/actions/asana-create-action-item | ||
| env: | ||
| html-notes: ${{ steps.update-asana.outputs.announcement-task-contents }} | ||
|
|
@@ -328,7 +355,8 @@ jobs: | |
|
|
||
| needs: [publish-to-sparkle] | ||
|
|
||
| if: ${{ github.event.inputs.release-type != 'internal' }} | ||
| # Run if release-type is provided (not empty) an is not internal | ||
| if: contains(github.event.inputs.release-type, '') == false && github.event.inputs.release-type != 'internal' | ||
|
|
||
| uses: duckduckgo/macos-browser/.github/workflows/create_variants.yml@main | ||
| secrets: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,11 @@ on: | |
| description: "Is this a pre-release? (a.k.a. internal release)" | ||
| required: true | ||
| type: boolean | ||
| internal-release-bump: | ||
| description: "Is this an internal release bump? (the subsequent internal release of the current week)" | ||
| required: false | ||
| default: false | ||
| type: boolean | ||
| secrets: | ||
| ASANA_ACCESS_TOKEN: | ||
| required: true | ||
|
|
@@ -57,6 +62,7 @@ jobs: | |
| BASE_BRANCH: ${{ inputs.base-branch || 'main' }} | ||
| BRANCH: ${{ inputs.branch || github.ref_name }} | ||
| prerelease: ${{ github.event.inputs.prerelease || inputs.prerelease }} | ||
| internal-release-bump: ${{ inputs.internal-release-bump }} | ||
|
|
||
| outputs: | ||
| tag: ${{ steps.create-tag.outputs.tag }} | ||
|
|
@@ -84,6 +90,16 @@ jobs: | |
| prerelease: ${{ env.prerelease }} | ||
| github-token: ${{ github.token }} | ||
|
|
||
| - name: Store created tag in a file artifact | ||
| run: echo ${{ steps.create-tag.outputs.tag }} > .github/tag | ||
|
|
||
| - name: Upload tag artifact | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: tag | ||
| path: .github/tag | ||
| retention-days: 1 | ||
|
|
||
| - name: Merge to base branch | ||
| id: merge | ||
| if: ${{ env.prerelease == 'true' }} | ||
|
|
@@ -106,7 +122,7 @@ jobs: | |
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| gh api --method DELETE /repos/${{ github.repository }}/git/refs/heads/${{ env.BRANCH}} | ||
| gh api --method DELETE /repos/${{ github.repository }}/git/refs/heads/${{ env.BRANCH }} | ||
|
|
||
| - name: Set common environment variables | ||
| if: always() | ||
|
|
@@ -163,6 +179,17 @@ jobs: | |
| release-task-url: ${{ env.asana-task-url }} | ||
| template-name: ${{ steps.asana-failure-templates.outputs.task-template }} | ||
|
|
||
| - name: Create Publish DMG Release task on failure | ||
| id: create-publish-dmg-task-on-failure | ||
| if: failure() && env.internal-release-bump == 'true' | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We only want this (break the workflow and ask release DRI to publish manually) on a proper failure ( |
||
| uses: ./.github/actions/asana-create-action-item | ||
| env: | ||
| ASANA_TASK_URL: ${{ env.asana-task-url }} | ||
| with: | ||
| access-token: ${{ secrets.ASANA_ACCESS_TOKEN }} | ||
| release-task-url: ${{ env.asana-task-url }} | ||
| template-name: run-publish-dmg-release | ||
|
|
||
| - name: Report failure | ||
| if: failure() || env.MERGE_OR_DELETE_FAILED == 'true' | ||
| uses: ./.github/actions/asana-log-message | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is lame - it should be a separate template, but I didn't have time for it now.