Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automate releasing embedding SDK #42516

Merged
merged 47 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
47b59eb
WIP some workflows
WiNloSt May 10, 2024
b54a881
Merge branch 'master' into 42498-automate-sdk-release
WiNloSt May 13, 2024
453e1bf
Add reminder todo comment
WiNloSt May 13, 2024
97c06f7
Complete the workflow
WiNloSt May 13, 2024
c038d2e
Fix YAML syntax error
WiNloSt May 13, 2024
7997bc5
Trigger the workflow
WiNloSt May 13, 2024
97bd6ba
Fix resuable workflow
WiNloSt May 13, 2024
045964e
Fix uberjar workflow
WiNloSt May 13, 2024
273d6f7
Add missing steps before testing
WiNloSt May 13, 2024
920cc53
Pass recrets to resuable workflow, so it could run
WiNloSt May 13, 2024
7642849
Fix sdk artifact location
WiNloSt May 13, 2024
1bbd1bd
Remove unneeded output
WiNloSt May 13, 2024
8930d72
fetch tags, so it doesn't fail on push
WiNloSt May 13, 2024
d3c3fd8
Only running EE uberjar in SDK workflow
WiNloSt May 13, 2024
6f75cdd
Fix incorrect syntax
WiNloSt May 13, 2024
2b014db
Shuffle workflow so it failed fast
WiNloSt May 13, 2024
584de89
Fix syntax error
WiNloSt May 13, 2024
7ec3903
Attempt to bulid only EE jar
WiNloSt May 13, 2024
efdef6f
Fix the error handling step
WiNloSt May 13, 2024
4a0b355
Merge branch 'master' into 42498-automate-sdk-release
WiNloSt May 14, 2024
d0c32e0
Fix failing to upload to s3
WiNloSt May 14, 2024
a6d4306
Fix create a PR step
WiNloSt May 14, 2024
581c53d
Fix the last temporary command, so the build looks green
WiNloSt May 14, 2024
7ed56f8
Remove hack to trigger the workflow
WiNloSt May 14, 2024
91fbea7
Remove completed todo comment
WiNloSt May 14, 2024
27bbf85
Clean up S3 step
WiNloSt May 14, 2024
2037edd
Merge branch 'master' into 42498-automate-sdk-release
WiNloSt May 15, 2024
d39e5f0
Add todo comment
WiNloSt May 15, 2024
31989fd
Upload correct docker image name
WiNloSt May 15, 2024
9876036
Bump the package version before building SDK
WiNloSt May 15, 2024
827154c
Fix uploading the correct Metabase dev container name
WiNloSt May 15, 2024
8f6d3ab
Fix one too many double quote
WiNloSt May 15, 2024
59a2ded
Push the correct docker image
WiNloSt May 15, 2024
032e512
Fix PR creation step
WiNloSt May 15, 2024
0d29c66
Dry run publishing SDK
WiNloSt May 15, 2024
1b52957
Merge branch 'master' into 42498-automate-sdk-release
WiNloSt May 16, 2024
4f03563
Use a separate uberjar workflow for SDK
WiNloSt May 16, 2024
ec77bbe
Remove a bunch of unused steps
WiNloSt May 16, 2024
0639cfb
Update variable names, step names
WiNloSt May 16, 2024
0e3b35f
Improve tag error message
WiNloSt May 16, 2024
46c0ee9
Correct m2-cache-key to be unique
WiNloSt May 16, 2024
5df46dd
Fix the push tag failure step to only run when failed to push tag
WiNloSt May 16, 2024
025d62c
Fix changed artifact name
WiNloSt May 16, 2024
87b22fc
Improve env name for clarity
WiNloSt May 16, 2024
a4fbb2d
Fix extra trailing empty line
WiNloSt May 16, 2024
f97ed74
Remove conditions from running certian steps
WiNloSt May 16, 2024
81e4907
Removing npm publish dry-run
WiNloSt May 16, 2024
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
180 changes: 180 additions & 0 deletions .github/workflows/release-embedding-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
name: Release Metabase Embedding SDK for React

on:
workflow_dispatch:
heypoom marked this conversation as resolved.
Show resolved Hide resolved
inputs:
sdk_version:
description: 'SDK version (e.g. 0.1.3)'
WiNloSt marked this conversation as resolved.
Show resolved Hide resolved
type: string
required: true
commit:
description: 'Optional full-length commit SHA-1 hash'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to make commit required in the future.
This really depends on how we end up using this workflow, or rather - what are we going to "tie" the SDK to.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0639cfb

# Force trigger the workflow
pull_request:
branches:
- 42498-automate-sdk-release


concurrency:
# We want to ensure only one job is running at a time because
# there could be a conflict when updating the readme file.
group: ${{ github.workflow }}
cancel-in-progress: true
Comment on lines +16 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👌


jobs:
git-tag:
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Check out the code using the provided commit, or HEAD
uses: actions/checkout@v4
with:
ref: ${{ inputs.commit }}

- name: Setup git user
run: |
git config --global user.email "metabase-bot@metabase.com"
git config --global user.name "Metabase bot"

- name: Create a new git tag
run: |
git tag embedding-sdk-${{ inputs.sdk_version }}

- name: Push the new tag
run: |
git push origin embedding-sdk-${{ inputs.sdk_version }}
- if: failure()
run: echo "Make sure the tag 'embedding-sdk-${{ inputs.sdk_version }}' doesn't exist."

test:
needs: git-tag
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Check out the code using the provided commit, or HEAD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the description to reflect the proper ref used here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0639cfb

uses: actions/checkout@v4
with:
ref: ${{ inputs.commit }}

- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend

- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
with:
m2-cache-key: "cljs"

- name: Run unit tests
run: yarn embedding-sdk:test-unit

build-sdk:
WiNloSt marked this conversation as resolved.
Show resolved Hide resolved
needs: test
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Check out the code using the provided commit, or HEAD
uses: actions/checkout@v4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: wondering if we can cache the checkout here with https://github.com/actions/cache since we checked out twice. let's worry about this later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with:
ref: ${{ inputs.commit }}

- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend

- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
with:
m2-cache-key: "cljs"
Copy link
Contributor

@heypoom heypoom May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if this process is the same as above (test), I wonder if we can cache this process

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, maybe we could bundle it. Although, the workflow would look cleaner since each job is responsible for certain things.
image

Edited: It seems our FE and BE preparation are already using cache for some steps, so they're not too slow. I don't think this should be a concern.

Also, I deliberately have test separated here because it's a sanity check if we could run the next 2 jobs in parallel (see the above workflow visualization) if we bundle build-sdk with test we probably have to do the same with build-jar

image


- name: Build SDK bundle
run: yarn run build-embedding-sdk

- name: Generate SDK package.json in the build directory
run: yarn run embedding-sdk:generate-package

- name: Upload built package as artifact
uses: actions/upload-artifact@v4
with:
name: metabase-${{ github.sha }}-sdk
path: ./resources/embedding-sdk
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the version gets bumped before this step? I see we bumped the version before creating a PR below, but I don't think we bumped the version of either package.template.json or the built artifact in resources/embedding-sdk. Otherwise the NPM package would be the old version

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this step is still incorrect as pointed out here. I'll fix this.


build-jar:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for me to understand - why do we need to build and upload jar?
I would assume - to make sure clients use specific metabase version that we tested with SDK, right?

Copy link
Member Author

@WiNloSt WiNloSt May 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for now, we say the jar built with the same commit as the SDK would be compatible with the SDK, this could change when we start shipping Metabase v0.50. I think we mentioned we'll then use the jar from the release branch, but I'm not totally 100% sure what commit we'll use in that case.

For more context:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this has the chance to be only a temporary solution, I wouldn't alter the existing uberjar.yml workflow (it's heavy already).

WDYT about creating a temporary uberjar-sdk.yml instead?
The benefit is that you can create it either as a workflow or as a composite action even.

I feel 90% confident that we should not modify the existing uberjar workflow for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 4f03563

needs: test
# TODO: Make it so that it only build EE jar, so we don't have to waste another runner for the image we don't use.
uses: ./.github/workflows/uberjar.yml
with:
commit: ${{ inputs.commit }}
only_ee: true
secrets: inherit
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed, otherwise uberjar workflow won't be able to access secrets.*. Alternatively we could specify which secrets we want to pass to it, but we can just use inherit which passes all secrets.


upload-jar:
needs: build-jar
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- uses: actions/download-artifact@v4
name: Retrieve uberjar artifact
with:
name: metabase-ee-${{ github.sha }}-uberjar

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_S3_RELEASE_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_S3_RELEASE_SECRET_ACCESS_KEY }}
aws-region: ${{ vars.AWS_REGION }}

- name: Upload uberjar to S3
env:
BUCKET: ${{ vars.AWS_S3_DOWNLOADS_BUCKET }}
BUCKET_PATH: sdk/v${{ inputs.sdk_version }}/metabase.jar
OUTPUT_FILE: ./target/uberjar/metabase.jar
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the name "output file" a bit ambiguous in this context as it's used as the first parameter of cp, can we just inline it in the cp command as it seems it's only used once?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I shamelessly copied that from

BUCKET: ${{ inputs.bucket }}
OUTPUT_FILE: ${{ inputs.output-name }}
😅 .

The reason I don't inline all of theme since it makes it hard to read since the line would be superlong. Would renaming this env instead help? e.g. INPUT_FILE or just FILE since we're copying files also I think we don't need a bracket just $FILE should work

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 87b22fc

shell: bash
run: | # sh
DATE=$(date '+%Y-%m-%d')
aws s3 cp ${OUTPUT_FILE} s3://$BUCKET/$BUCKET_PATH


publish-npm:
needs: [build-sdk, upload-jar]
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Check out the code using the provided commit, or HEAD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the description, or omit it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 0639cfb

uses: actions/checkout@v4
with:
ref: ${{ inputs.commit }}

- name: Setup git user
run: |
git config --global user.email "metabase-bot@metabase.com"
git config --global user.name "Metabase bot"

- name: Update readme
run: |
sed -i -E 's|(embedding-sdk-)[0-9.]+|\1${{ inputs.sdk_version }}|' enterprise/frontend/src/embedding-sdk/README.md
sed -i -E 's|(http://downloads.metabase.com/sdk/v)[0-9.]+|\1${{ inputs.sdk_version }}|' enterprise/frontend/src/embedding-sdk/README.md
Comment on lines +158 to +159
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified locally that regex here works.

I wonder if we should run this as part of the README copy function in generate-sdk-package-files though. We currently run copyFileToOutput("frontend/src/embedding-sdk/README.md", "README.md");, so we could as easily modify the content there. I guess we do this because we want to bump the version without relying on the script?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I just think of this step as a separate one from generating the package.json which generate-sdk-package-files.js handles.

However, generate-sdk-package-files already accepts an argument as a commit hash, I'm not very familiar with writing CLI, so we could accept named argument instead so I could do --version=<new_version> without having to pass the commit hash.

This could surely become an improvement later on.


- name: Bump published npm package version
run: |
sed -i -E 's/("version": ").*"/\1${{ inputs.sdk_version }}"/' enterprise/frontend/src/embedding-sdk/package.template.json

- uses: actions/create-github-app-token@v1
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses GitHub's own https://github.com/actions/create-github-app-token action rather than a 3rd party one we used in other workflow e.g.

- uses: tibdex/github-app-token@v2.1.0
id: generate-token
with:
app_id: ${{ secrets.METABASE_BOT_APP_ID }}
private_key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}

id: app-token
with:
app-id: ${{ secrets.METABASE_BOT_APP_ID }}
private-key: ${{ secrets.METABASE_BOT_APP_PRIVATE_KEY }}

- name: Create a PR updating readme + published version
WiNloSt marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure, this PR that gets created will update the versions, but the package with the specified version will already be published right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, but to be specific the package would be published in the last step within this job. The PR would have been created at this step and we will have to manually merge the PR.

Realistically, by the time we look at the PR, the SDK package would already likely be published.

run: |
git checkout -b update-sdk-version-${{ inputs.sdk_version }}
git commit -a -m 'Update Readme version references and published npm version to ${{ inputs.sdk_version }}'
git push origin HEAD
gh pr create --base master\
--assignee "${GITHUB_ACTOR}"\
--title "Update SDK version to ${{ inputs.sdk_version }}"\
--body "Update Readme version references and published npm package version to ${{ inputs.sdk_version }}"
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}

- name: Publish to NPM
run: echo "Implement this step once you've ensure other steps works correctly.""
24 changes: 17 additions & 7 deletions .github/workflows/uberjar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ on:
inputs:
commit:
description: 'Optional full-length commit SHA-1 hash'
# This workflow will be called from "release-embedding-sdk.yml"
workflow_call:
inputs:
commit:
description: 'Optional full-length commit SHA-1 hash'
type: string
only_ee:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a better way to allow parameterizing matrix. Please let me know if there's more ideal way to go about this.

description: A flag to indicate if only EE Uberjar should be built.
type: boolean
default: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a situation where only_ee would be false? I thought we always only need the EE uberjar

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this case, no. workflow_call is only being called from the SDK. But I think it's great to be explicit, so folks who care about uberjar.yml could know that it should behave the same by building 2 jars for all existing use cases.

Also, this corresponds to workflow_dispatch's inputs.only_ee which should be evaluated to falsy value since only_ee isn't defined in workflow_dispatch


jobs:
build:
Expand All @@ -26,15 +36,15 @@ jobs:
timeout-minutes: 40
strategy:
matrix:
edition: [ee, oss]
edition: ${{ fromJSON(inputs.only_ee && '["ee"]' || '["ee", "oss"]') }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a way to parameterize matrix. This is needed because when we build the SDK, we only want to build the EE jar.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we shouldn't modify the existing workflow.
But if we do end up doing that, the alternative to parameterizing the matrix is to have a conditional step execution. You can provide something like if workflow_call AND edition is EE, then execute this step.

This comes with tradeoffs, for sure.
If you have to do this for every single step out there, then it makes sense to parameterize the matrix, for sure.

Please check include and exclude

env:
MB_EDITION: ${{ matrix.edition }}
INTERACTIVE: false
steps:
- name: Check out the code
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.commit }}
ref: ${{ inputs.commit }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor github.event.inputs to inputs most of the time they are equivalent for workflow_dispatch except inputs preserve the boolean value..

However, the main thing is to make it consistent with workflow_call since only inputs is available for workflow_call not github.even.inputs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the commit that comes from SDK is optional.
Which means that it's going to default to the HEAD.

So what happens in SDK builds from commit abc on master, and by the time this workflow kicks in someone pushed another commit. In that case the uberjar workflow will build from commit def.

This is not hard to imagine given the frequency we push to master (especially just prior to the release).

- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend
- name: Prepare back-end environment
Expand All @@ -55,7 +65,7 @@ jobs:
timeout-minutes: 10
strategy:
matrix:
edition: [ee, oss]
edition: ${{ fromJSON(inputs.only_ee && '["ee"]' || '["ee", "oss"]') }}
java-version: [11, 17]
steps:
- name: Prepare JRE (Java Run-time Environment)
Expand All @@ -80,7 +90,7 @@ jobs:
needs: check_jar_health
strategy:
matrix:
edition: [ee, oss]
edition: ${{ fromJSON(inputs.only_ee && '["ee"]' || '["ee", "oss"]') }}
services:
registry:
image: registry:2
Expand All @@ -96,7 +106,7 @@ jobs:
- name: Check out the code (Dockerfile needed)
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.commit }}
ref: ${{ inputs.commit }}
- name: Download uploaded artifacts to insert into container
uses: actions/download-artifact@v4
with:
Expand Down Expand Up @@ -197,7 +207,7 @@ jobs:
needs: check_jar_health
strategy:
matrix:
edition: [ee, oss]
edition: ${{ fromJSON(inputs.only_ee && '["ee"]' || '["ee", "oss"]') }}
services:
registry:
image: registry:2
Expand All @@ -213,7 +223,7 @@ jobs:
- name: Check out the code (Dockerfile needed)
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.commit }}
ref: ${{ inputs.commit }}
- name: Download uploaded artifacts to insert into container
uses: actions/download-artifact@v4
with:
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@
"embedding-sdk:fixup-types-imports": "node ./bin/embedding-sdk/fixup-types-after-compilation.js",
"embedding-sdk:generate-package": "node ./bin/embedding-sdk/generate-sdk-package-files.js",
"embedding-sdk:publish": "cd ./resources/embedding-sdk && npm publish",
"embedding-sdk:test-unit": "yarn test-unit enterprise/frontend/src/embedding-sdk/",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a simple sanity check for SDK, we have more tests when running the uberjar workflow already.

"eslint-fix": "yarn lint-eslint --fix",
"generate-cypress-html-report": "mochawesome-merge cypress/reports/mochareports/*.json > cypress/reports/cypress-test-report.json && marge cypress/reports/cypress-test-report.json -o cypress/reports/mochareports --inline",
"lint": "yarn lint-eslint && yarn lint-prettier && yarn lint-docs-links && yarn lint-yaml && yarn type-check",
Expand Down
Loading