Skip to content
Snippets Groups Projects
Unverified Commit 384af816 authored by Ryan Laurie's avatar Ryan Laurie Committed by GitHub
Browse files

Release from tagged test jars (#43545)

* allow releasing from tagged test jars

* always listen to nemanja

* use java 17
parent 5b5b0597
No related branches found
No related tags found
No related merge requests found
name: Prepare front-end environment
inputs:
node-version:
description: "The version of Node.js to use, overriding .nvmrc"
required: false
runs:
using: "composite"
steps:
- name: Prepare Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }} # this overrides, if present
node-version-file: ".nvmrc"
- name: Check to see if dependencies should be cached
if: ${{ contains(github.event.head_commit.message, '[ci nocache]') }}
......
......@@ -39,8 +39,39 @@ jobs:
id: e2e-matrix
uses: ./.github/actions/build-e2e-matrix
# if this is a test on a release branch, we need to check the build requirements
get-build-requirements:
if: |
!cancelled() &&
contains(github.ref, 'release-x')
runs-on: ubuntu-22.04
timeout-minutes: 10
outputs:
java_version: ${{ fromJson(steps.dependencies.outputs.result).java_version }}
node_version: ${{ fromJson(steps.dependencies.outputs.result).node_version }}
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: release
- name: Prepare build scripts
run: cd ${{ github.workspace }}/release && yarn && yarn build
- name: Get build dependencies
uses: actions/github-script@v7
id: dependencies
with:
script: | # js
const { getBuildRequirements, getVersionFromReleaseBranch } = require('${{ github.workspace }}/release/dist/index.cjs');
const version = getVersionFromReleaseBranch('${{ github.ref }}');
const requirements = getBuildRequirements(version);
return {
java_version: requirements.java,
node_version: requirements.node,
};
build:
needs: [files-changed, e2e-matrix-builder]
needs: [files-changed, e2e-matrix-builder, get-build-requirements]
if: |
!cancelled() &&
github.event.pull_request.draft == false &&
......@@ -58,10 +89,13 @@ jobs:
- uses: actions/checkout@v4
- name: Prepare front-end environment
uses: ./.github/actions/prepare-frontend
with:
node-version: '${{ needs.get-build-requirements.outputs.node_version }}'
- name: Prepare back-end environment
uses: ./.github/actions/prepare-backend
with:
m2-cache-key: e2e-tests
java-version: '${{ needs.get-build-requirements.outputs.java_version || 11 }}'
- name: Build uberjar with ./bin/build.sh
run: ./bin/build.sh
......
name: Release 1a - Tag Release Artifact
run-name: Tag ${{ inputs.version }}
on:
workflow_dispatch:
inputs:
version:
description: 'Metabase version (e.g. v0.46.3)'
type: string
required: true
commit:
description: 'A full-length commit SHA-1 hash'
required: true
jobs:
start-message:
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
with:
sparse-checkout: release
- name: Prepare build scripts
run: cd ${{ github.workspace }}/release && yarn && yarn build
- name: Send build start message
uses: actions/github-script@v6
env:
SLACK_RELEASE_CHANNEL: ${{ vars.SLACK_RELEASE_CHANNEL }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
with:
script: | # js
const { sendReleaseMessage } = require('${{ github.workspace }}/release/dist/index.cjs');
await sendReleaseMessage({
stage: 'build-start',
github,
owner: context.repo.owner,
repo: context.repo.repo,
version: '${{ inputs.version }}',
runId: '${{ github.run_id }}',
releaseSha: '${{ inputs.commit }}',
}).catch(console.error);
check-version:
runs-on: ubuntu-22.04
timeout-minutes: 10
outputs:
ee: ${{ fromJson(steps.canonical_version.outputs.result).ee }}
oss: ${{ fromJson(steps.canonical_version.outputs.result).oss }}
steps:
- name: Fail early on the incorrect version format
if: ${{ !(startsWith(inputs.version,'v0.') || startsWith(inputs.version,'v1.')) }}
run: |
echo "The version format is invalid!"
echo "It must start with either 'v0.' or 'v1.'."
echo "Please, try again."
exit 1
- uses: actions/checkout@v4
with:
sparse-checkout: release
- name: Prepare build scripts
run: cd ${{ github.workspace }}/release && yarn && yarn build
- name: Get Release Version
uses: actions/github-script@v7
id: canonical_version
with:
script: | # js
const { isValidVersionString, getCanonicalVersion, hasBeenReleased } = require('${{ github.workspace }}/release/dist/index.cjs');
const version = '${{ inputs.version }}';
if (!isValidVersionString(version)) {
throw new Error("The version format is invalid! It must start with either 'v0.' or 'v1.'.");
}
const versions = {
ee: getCanonicalVersion(version, 'ee'),
oss: getCanonicalVersion(version, 'oss'),
};
const ossReleased = await hasBeenReleased({
github,
owner: context.repo.owner,
repo: context.repo.repo,
version: versions.oss,
});
const eeReleased = await hasBeenReleased({
github,
owner: context.repo.owner,
repo: context.repo.repo,
version: versions.ee,
});
if (ossReleased || eeReleased) {
throw new Error("This version has already been released!", version);
}
return versions;
check-commit:
runs-on: ubuntu-22.04
timeout-minutes: 10
steps:
- name: Check out the code to verify the release branch
uses: actions/checkout@v4
with:
fetch-depth: 0 # IMPORTANT! to get all the branches
sparse-checkout: release
- name: Prepare build scripts
run: cd ${{ github.workspace }}/release && yarn && yarn build
- name: Get Release Branch
uses: actions/github-script@v7
id: release_branch
with:
result_encoding: string
script: | # js
const { getReleaseBranch } = require('${{ github.workspace }}/release/dist/index.cjs');
const version = '${{ inputs.version }}';
const releaseBranch = getReleaseBranch(version);
return releaseBranch;
- name: Ensure that the specified commit exists in the ${{ steps.release_branch.outputs.result }} release branch
run: |
RELEASE_BRANCH=${{ steps.release_branch.outputs.result }}
git checkout $RELEASE_BRANCH
git branch --contains ${{ inputs.commit }} | grep -q $RELEASE_BRANCH \
&& echo "Commit found in correct release branch" \
|| (echo "Commit not found in correct release branch" && exit 1)
tag-uberjar-for-release:
needs: [check-version, check-commit]
runs-on: ubuntu-22.04
timeout-minutes: 10
strategy:
matrix:
edition: [oss, ee]
env:
INTERACTIVE: false
steps:
- name: Get correct version number
run: | # bash
if [ '${{matrix.edition}}' == 'ee' ]; then
version='${{ needs.check-version.outputs.ee }}'
else
version='${{ needs.check-version.outputs.oss }}'
fi
echo "VERSION=$version" >> $GITHUB_ENV
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17 # 11 throws an error on jar uf
- name: Retrieve test build uberjar artifact for ${{ matrix.edition }}
id: find_release_artifact
uses: actions/github-script@v7
with:
result-encoding: string
script: | # js
const fs = require('fs');
const artifacts = await github.rest.actions.listArtifactsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
name: `metabase-${{ matrix.edition }}-${{ inputs.commit }}-uberjar`,
per_page: 1,
});
if (!artifacts.data?.artifacts?.[0]?.id) {
console.warn(`No existing artifacts found for ${{ inputs.commit }}, need to build jar`);
if ("${{matrix.edition}}" === 'oss') {
// only trigger the build job on OSS, otherwise we'll get double builds
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'build-for-release.yml',
ref: 'refs/heads/master',
inputs: {
commit: '${{ inputs.commit }}',
version: '${{ inputs.version }}',
}
});
}
throw new Error('aborting in favor of build script');
}
const artifact_id = artifacts.data.artifacts[0].id;
const download = await github.rest.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: artifact_id,
archive_format: 'zip',
});
fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/mb.zip`, Buffer.from(download.data));
- name: Unzip Metabase artifact containing an uberjar
run: |
unzip mb.zip
mv target/uberjar/metabase.jar metabase.jar
- name: Update version.properties in jar
run: | # sh
jar xf metabase.jar version.properties
echo "Old version.properties:"
cat version.properties
sed -i "s/^tag=.*/tag=$VERSION/" version.properties
echo "\n\nNew version.properties:"
cat version.properties
echo "\n\nUpdating metabase.jar with new version.properties"
jar uf metabase.jar version.properties
- name: Store commit's SHA-1 hash
run: echo ${{ inputs.commit }} > COMMIT-ID
shell: bash
- name: Calculate SHA256 checksum
run: sha256sum ./metabase.jar > SHA256.sum
shell: bash
- name: Upload JARs as artifact
uses: actions/upload-artifact@v4
with:
name: metabase-release-${{ matrix.edition }}-${{ inputs.commit }}-uberjar
path: |
./metabase.jar
./COMMIT-ID
./SHA256.sum
trigger-tests:
needs: [tag-uberjar-for-release]
permissions:
actions: write
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
- name: trigger pre-release testing
uses: actions/github-script@v7
with:
script: | # js
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: 'pre-release.yml',
ref: '${{ github.ref }}',
inputs: {
commit: '${{ inputs.commit }}',
version: '${{ inputs.version }}',
}
});
......@@ -85,6 +85,16 @@ export const getReleaseBranch = (versionString: string) => {
return `release-x.${majorVersion}.x`;
};
export const getVersionFromReleaseBranch = (branch: string) => {
const match = /release-x\.(\d+)\.x$/.exec(branch);
if (!match) {
throw new Error(`Invalid release branch: ${branch}`);
}
const majorVersion = match[1];
return `v0.${majorVersion}.0`;
}
export const isLatestVersion = (thisVersion: string, allVersions: string[]) => {
if (isRCVersion(thisVersion)) {
return false;
......
......@@ -6,6 +6,7 @@ import {
isRCVersion,
getVersionType,
getReleaseBranch,
getVersionFromReleaseBranch,
isLatestVersion,
getBuildRequirements,
getNextVersions,
......@@ -193,6 +194,29 @@ describe("version-helpers", () => {
});
});
describe("getVersionFromReleaseBranch", () => {
it("should return the version from a valid release branch", () => {
const cases: [string, string][] = [
["/refs/heads/release-x.75.x", "v0.75.0"],
["release-x.7.x", "v0.7.0"],
["release-x.99.x", "v0.99.0"],
["abcrelease-x.12.x", "v0.12.0"],
["refs/heads/release-x.22.x", "v0.22.0"],
];
cases.forEach(([input, expected]) => {
expect(getVersionFromReleaseBranch(input)).toEqual(expected);
});
});
it("should throw an error for invalid release branches", () => {
const cases = ["foo", "release-x.75", "release-x.75.0", "release-x.75.x-test", "refs/heads/release-x"];
cases.forEach(input => {
expect(() => getVersionFromReleaseBranch(input)).toThrow();
});
});
});
describe("isLatestVersion", () => {
it(`should return true for latest releases`, () => {
const cases: [string, string[]][] = [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment