Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ data:
<body>
<h2>Internal release build ${TAG} ready ✅</h2>
<ul>
<li>📥 DMG is available from <a href='${DMG_URL}'>${DMG_URL}</a>.</li>
<li>📥 DMG is available from <a href='${DMG_URL}'>${DMG_URL}</a>.
<ul>
<li>If this is a subsequent internal release (started by calling <em>Bump Internal Release</em> workflow), the DMG will be automatically published to Sparkle in a few minutes. Sit tight.</li>
Copy link
Collaborator Author

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.

</ul></li>
<li>🏷️ Repository is tagged with <code>${TAG}</code> tag.</li>
<li>🚢 GitHub <a href='${RELEASE_URL}'>${TAG} pre-release</a> is created.</li>
<li>🔱 <code>${BRANCH}</code> branch has been successfully merged to <code>${BASE_BRANCH}</code>.</li>
Expand Down
4 changes: 4 additions & 0 deletions .github/actions/asana-create-action-item/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ runs:
shell: bash
env:
ASSIGNEE_ID: ${{ steps.get-automation-subtask.outputs.assignee-id }}
AUTOMATION_TASK_ID: ${{ steps.get-automation-subtask.outputs.automation-task-id }}
TEMPLATE_PATH: ${{ github.action_path }}/templates/${{ inputs.template-name }}.yml
WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
if [ ! -f $TEMPLATE_PATH ]; then
echo "::error::Template file not found at $TEMPLATE_PATH"
Expand All @@ -64,6 +66,7 @@ runs:
shell: bash
env:
ASSIGNEE_ID: ${{ steps.get-automation-subtask.outputs.assignee-id }}
AUTOMATION_TASK_ID: ${{ steps.get-automation-subtask.outputs.automation-task-id }}
NOTES: ${{ inputs.notes }}
TASK_NAME: ${{ inputs.task-name }}
WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
Expand All @@ -76,6 +79,7 @@ runs:
shell: bash
env:
ASSIGNEE_ID: ${{ steps.get-automation-subtask.outputs.assignee-id }}
AUTOMATION_TASK_ID: ${{ steps.get-automation-subtask.outputs.automation-task-id }}
HTML_NOTES: ${{ inputs.html-notes }}
TASK_NAME: ${{ inputs.task-name }}
WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
Expand Down
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
Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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>
3 changes: 2 additions & 1 deletion .github/actions/asana-log-message/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ inputs:
type: string
template-name:
description: |
Name of a template file (without extension) for the comment, relative to 'templates' subdirectory of the action.
Name of a template file (without extension) for the comment, relative to 'templates'
subdirectory of the 'asana-add-comment' action.
The file is processed by envsubst before being sent to Asana.
required: false
type: string
Expand Down

This file was deleted.

8 changes: 0 additions & 8 deletions .github/actions/asana-log-message/templates/dmg-uploaded.yml

This file was deleted.

This file was deleted.

This file was deleted.

14 changes: 14 additions & 0 deletions .github/workflows/bump_internal_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Collaborator Author

@ayoy ayoy Mar 4, 2024

Choose a reason for hiding this comment

The 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.

68 changes: 48 additions & 20 deletions .github/workflows/publish_dmg_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -43,6 +61,10 @@ jobs:

name: Publish a release to Sparkle

env:
RELEASE_TYPE: ${{ github.event.inputs.release-type || 'internal' }}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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)
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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 }}
Expand All @@ -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
Expand Down Expand Up @@ -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 }}
Expand Down Expand Up @@ -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:
Expand Down
29 changes: 28 additions & 1 deletion .github/workflows/tag_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 }}
Expand Down Expand Up @@ -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' }}
Expand All @@ -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()
Expand Down Expand Up @@ -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'
Copy link
Collaborator Author

@ayoy ayoy Mar 4, 2024

Choose a reason for hiding this comment

The 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 (failure()). This workflow does not treat merge conflict as failure so it moves on, and since merge conflict is not a blocker for releasing the build (that's already made and tagged in git after all), it gets published automatically on internal release bumps, and the release DRI needs to handle merging separately.

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
Expand Down