diff --git a/automation/utils/bin/rui-prepare-release.ts b/automation/utils/bin/rui-prepare-release.ts index d05d38cc42..253fe6a1a2 100644 --- a/automation/utils/bin/rui-prepare-release.ts +++ b/automation/utils/bin/rui-prepare-release.ts @@ -10,15 +10,29 @@ async function main(): Promise { try { console.log(chalk.bold.cyan("\nšŸš€ RELEASE PREPARATION WIZARD šŸš€\n")); - // Check for GitHub token - const githubToken = process.env.GH_PAT; - if (!githubToken) { - console.warn(chalk.yellow("āš ļø GH_PAT environment variable not set")); - console.warn(chalk.yellow(" GitHub workflow will need manual triggering")); + console.log(chalk.bold("šŸ“‹ STEP 1: Initialize Jira and GitHub")); + + // Check GitHub authentication + try { + await gh.ensureAuth(); + console.log(chalk.green("āœ… GitHub authentication verified")); + } catch (error) { + console.log(chalk.red(`āŒ GitHub authentication failed: ${(error as Error).message}`)); + console.log(chalk.yellow("\nšŸ’” First, make sure GitHub CLI is installed:")); + console.log(chalk.cyan(" Download from: https://cli.github.com/")); + console.log(chalk.cyan(" Or install via brew: brew install gh")); + console.log(chalk.yellow("\nšŸ’” Then authenticate with GitHub using one of these options:")); + console.log(chalk.yellow(" 1. Set GITHUB_TOKEN environment variable:")); + console.log(chalk.cyan(" export GITHUB_TOKEN=your_token_here")); + console.log(chalk.yellow(" 2. Set GH_PAT environment variable:")); + console.log(chalk.cyan(" export GH_PAT=your_token_here")); + console.log(chalk.yellow(" 3. Use GitHub CLI to authenticate:")); + console.log(chalk.cyan(" gh auth login")); + console.log(chalk.yellow("\n Get a token at: https://github.com/settings/tokens")); + process.exit(1); } // Step 1: Initialize Jira client - console.log(chalk.bold("šŸ“‹ STEP 1: Initialize Jira")); let jira: Jira; try { jira = await initializeJiraClient(); @@ -87,7 +101,7 @@ async function main(): Promise { console.log(chalk.green("āœ… Branch pushed to GitHub")); console.log(chalk.bold("\nšŸ“‹ STEP 5: GitHub Release Workflow")); - await triggerGitHubReleaseWorkflow(pkg.name, tmpBranchName, githubToken); + await triggerGitHubReleaseWorkflow(pkg.name, tmpBranchName); console.log(chalk.bold("\nšŸ“‹ STEP 6: Jira Issue Management")); await manageIssuesForVersion(jira, jiraVersion.id, jiraVersionName); @@ -229,29 +243,21 @@ async function manageIssuesForVersion(jira: Jira, versionId: string, versionName } } -async function triggerGitHubReleaseWorkflow( - packageName: string, - branchName: string, - githubToken?: string -): Promise { - if (githubToken) { - const { triggerWorkflow } = await prompt<{ triggerWorkflow: boolean }>({ - type: "confirm", - name: "triggerWorkflow", - message: "ā“ Trigger GitHub release workflow now?", - initial: true - }); +async function triggerGitHubReleaseWorkflow(packageName: string, branchName: string): Promise { + const { triggerWorkflow } = await prompt<{ triggerWorkflow: boolean }>({ + type: "confirm", + name: "triggerWorkflow", + message: "ā“ Trigger GitHub release workflow now?", + initial: true + }); - if (triggerWorkflow) { - console.log(chalk.blue("šŸ”„ Triggering GitHub release workflow...")); - try { - await gh.triggerCreateReleaseWorkflow(packageName, branchName); - console.log(chalk.green("āœ… GitHub Release Workflow triggered")); - } catch (error) { - console.error(chalk.red(`āŒ Failed to trigger workflow: ${(error as Error).message}`)); - showManualTriggerInstructions(packageName, branchName); - } - } else { + if (triggerWorkflow) { + console.log(chalk.blue("šŸ”„ Triggering GitHub release workflow...")); + try { + await gh.triggerCreateReleaseWorkflow(packageName, branchName); + console.log(chalk.green("āœ… GitHub Release Workflow triggered")); + } catch (error) { + console.error(chalk.red(`āŒ Failed to trigger workflow: ${(error as Error).message}`)); showManualTriggerInstructions(packageName, branchName); } } else { @@ -260,7 +266,7 @@ async function triggerGitHubReleaseWorkflow( } async function createReleaseBranch(packageName: string, version: string): Promise { - const tmpBranchName = `tmp-release/${packageName}-v${version}`; + const tmpBranchName = `tmp/${packageName}-v${version}`; let branchToUse = tmpBranchName; let branchesAreReady = false; @@ -347,7 +353,6 @@ async function createReleaseBranch(packageName: string, version: string): Promis } async function initializeJiraClient(): Promise { - console.log(chalk.bold("šŸ” Checking Jira environment variables")); const projectKey = process.env.JIRA_PROJECT_KEY; const baseUrl = process.env.JIRA_BASE_URL; const apiToken = process.env.JIRA_API_TOKEN; @@ -358,6 +363,7 @@ async function initializeJiraClient(): Promise { console.log(chalk.dim(" export JIRA_PROJECT_KEY=WEB")); console.log(chalk.dim(" export JIRA_BASE_URL=https://your-company.atlassian.net")); console.log(chalk.dim(" export JIRA_API_TOKEN=username@your-company.com:ATATT3xFfGF0...")); + console.log(chalk.dim(" Get your API token at: https://id.atlassian.com/manage-profile/security/api-tokens")); throw new Error("Missing Jira environment variables"); } diff --git a/automation/utils/docker/mxbuild.Dockerfile b/automation/utils/docker/mxbuild.Dockerfile index 7885937ebb..ba69d1f0a7 100644 --- a/automation/utils/docker/mxbuild.Dockerfile +++ b/automation/utils/docker/mxbuild.Dockerfile @@ -1,28 +1,38 @@ -FROM mono:6.12 +FROM --platform=$BUILDPLATFORM eclipse-temurin:17-jdk-jammy + ARG MENDIX_VERSION +ARG BUILDPLATFORM +SHELL ["/bin/bash", "-c"] RUN \ - echo "Installing Java..." && \ - apt-get -qq update && \ - apt-get -qq install -y wget && \ - wget -q https://download.java.net/java/GA/jdk11/9/GPL/openjdk-11.0.2_linux-x64_bin.tar.gz -O /tmp/openjdk.tar.gz && \ - mkdir /usr/lib/jvm && \ - tar xfz /tmp/openjdk.tar.gz --directory /usr/lib/jvm && \ - rm /tmp/openjdk.tar.gz && \ -\ - echo "Downloading mxbuild ${MENDIX_VERSION}..." && \ - wget -q https://cdn.mendix.com/runtime/mxbuild-${MENDIX_VERSION}.tar.gz -O /tmp/mxbuild.tar.gz && \ - mkdir /tmp/mxbuild && \ - tar xfz /tmp/mxbuild.tar.gz --directory /tmp/mxbuild && \ - rm /tmp/mxbuild.tar.gz && \ +echo "Downloading mxbuild ${MENDIX_VERSION} and docker building for ${BUILDPLATFORM}..." \ + && case "${BUILDPLATFORM}" in \ + linux/arm64) \ + BINARY_URL="https://cdn.mendix.com/runtime/arm64-mxbuild-${MENDIX_VERSION}.tar.gz"; \ + ;; \ + linux/amd64) \ + BINARY_URL="https://cdn.mendix.com/runtime/mxbuild-${MENDIX_VERSION}.tar.gz"; \ + ;; \ + *) \ + echo "Unsupported architecture: ${BUILDPLATFORM}" >&2; \ + exit 1; \ + ;; \ + esac \ + && echo "Downloading from: ${BINARY_URL}" \ + && wget -q "${BINARY_URL}" -O /tmp/mxbuild.tar.gz \ + && mkdir /tmp/mxbuild \ + && tar xfz /tmp/mxbuild.tar.gz --directory /tmp/mxbuild \ + && rm /tmp/mxbuild.tar.gz && \ \ - apt-get -qq remove -y wget && \ + apt-get update -qqy && \ + apt-get install -qqy libicu70 libgdiplus && \ + apt-get -qqy remove --auto-remove wget && \ apt-get clean && \ \ echo "#!/bin/bash -x" >/bin/mxbuild && \ - echo "mono /tmp/mxbuild/modeler/mxbuild.exe --java-home=/usr/lib/jvm/jdk-11.0.2 --java-exe-path=/usr/lib/jvm/jdk-11.0.2/bin/java \$@" >>/bin/mxbuild && \ + echo "/tmp/mxbuild/modeler/mxbuild --java-home=/opt/java/openjdk --java-exe-path=/opt/java/openjdk/bin/java \$@" >>/bin/mxbuild && \ chmod +x /bin/mxbuild && \ \ echo "#!/bin/bash -x" >/bin/mx && \ - echo "mono /tmp/mxbuild/modeler/mx.exe \$@" >>/bin/mx && \ + echo "/tmp/mxbuild/modeler/mx \$@" >>/bin/mx && \ chmod +x /bin/mx diff --git a/automation/utils/docker/mxbuildMx10.Dockerfile b/automation/utils/docker/mxbuildMx10.Dockerfile deleted file mode 100644 index eb0cbe77c9..0000000000 --- a/automation/utils/docker/mxbuildMx10.Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -FROM --platform=$BUILDPLATFORM eclipse-temurin:17-jdk-jammy - -ARG MENDIX_VERSION -ARG BUILDPLATFORM - -SHELL ["/bin/bash", "-c"] -RUN \ -echo "Downloading mxbuild ${MENDIX_VERSION} and docker building for ${BUILDPLATFORM}..." \ - && case "${BUILDPLATFORM}" in \ - linux/arm64) \ - BINARY_URL="https://cdn.mendix.com/runtime/arm64-mxbuild-${MENDIX_VERSION}.tar.gz"; \ - ;; \ - linux/amd64) \ - BINARY_URL="https://cdn.mendix.com/runtime/mxbuild-${MENDIX_VERSION}.tar.gz"; \ - ;; \ - *) \ - echo "Unsupported architecture: ${BUILDPLATFORM}" >&2; \ - exit 1; \ - ;; \ - esac \ - && echo "Downloading from: ${BINARY_URL}" \ - && wget -q "${BINARY_URL}" -O /tmp/mxbuild.tar.gz \ - && mkdir /tmp/mxbuild \ - && tar xfz /tmp/mxbuild.tar.gz --directory /tmp/mxbuild \ - && rm /tmp/mxbuild.tar.gz && \ -\ - apt-get update -qqy && \ - apt-get install -qqy libicu70 && \ - apt-get -qqy remove --auto-remove wget && \ - apt-get clean && \ -\ - echo "#!/bin/bash -x" >/bin/mxbuild && \ - echo "/tmp/mxbuild/modeler/mxbuild --java-home=/opt/java/openjdk --java-exe-path=/opt/java/openjdk/bin/java \$@" >>/bin/mxbuild && \ - chmod +x /bin/mxbuild && \ -\ - echo "#!/bin/bash -x" >/bin/mx && \ - echo "/tmp/mxbuild/modeler/mx \$@" >>/bin/mx && \ - chmod +x /bin/mx diff --git a/automation/utils/src/github.ts b/automation/utils/src/github.ts index 647bee39d7..ef5f7c92d0 100644 --- a/automation/utils/src/github.ts +++ b/automation/utils/src/github.ts @@ -30,9 +30,33 @@ export class GitHub { authSet = false; tmpPrefix = "gh-"; - private async ensureAuth(): Promise { + async ensureAuth(): Promise { if (!this.authSet) { - await exec(`echo "${process.env.GH_PAT}" | gh auth login --with-token`); + if (process.env.GITHUB_TOKEN) { + // when using GITHUB_TOKEN, gh will automatically use it + } else if (process.env.GH_PAT) { + await exec(`echo "${process.env.GH_PAT}" | gh auth login --with-token`); + } else { + // No environment variables set, check if already authenticated + if (!(await this.isAuthenticated())) { + throw new Error( + "GitHub CLI is not authenticated. Please set GITHUB_TOKEN or GH_PAT environment variable, or run 'gh auth login'." + ); + } + } + + this.authSet = true; + } + } + + private async isAuthenticated(): Promise { + try { + // Try to run 'gh auth status' to check if authenticated + await exec("gh auth status", { stdio: "pipe" }); + return true; + } catch (error) { + // If the command fails, the user is not authenticated + return false; } } diff --git a/automation/utils/src/mpk.ts b/automation/utils/src/mpk.ts index d4b21508f8..dd30881cd5 100644 --- a/automation/utils/src/mpk.ts +++ b/automation/utils/src/mpk.ts @@ -9,11 +9,7 @@ async function ensureMxBuildDockerImageExists(mendixVersion: Version): Promise= 10 - ? "/tmp/mxbuild/modeler/mx create-module-package" - : "/tmp/mxbuild/modeler/mxutil.exe create-module-package", + versionMajor < 10 ? "/tmp/mxbuild/modeler/mxutil" : "/tmp/mxbuild/modeler/mx", + "create-module-package", excludeFilesRegExp ? `--exclude-files='${excludeFilesRegExp}'` : "", `/source/${projectFile}`, moduleName diff --git a/package.json b/package.json index 560f3aa897..aa5c2d9994 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "publish-marketplace": "turbo run publish-marketplace", "version": "pnpm --filter @mendix/automation-utils run version", "changelog": "pnpm --filter @mendix/automation-utils run changelog", + "prepare-release": "pnpm --filter @mendix/automation-utils run prepare-release", "postinstall": "turbo run agent-rules" }, "devDependencies": {