diff --git a/.github/scripts/package-lock.json b/.github/scripts/package-lock.json deleted file mode 100644 index 9dfdf84a..00000000 --- a/.github/scripts/package-lock.json +++ /dev/null @@ -1,255 +0,0 @@ -{ - "name": "scripts", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@octokit/rest": "^22.0.1", - "simple-git": "^3.32.2" - } - }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1" - } - }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==", - "license": "MIT" - }, - "node_modules/@octokit/auth-token": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", - "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", - "license": "MIT", - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/core": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.6.tgz", - "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", - "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^6.0.0", - "@octokit/graphql": "^9.0.3", - "@octokit/request": "^10.0.6", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "before-after-hook": "^4.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/endpoint": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.3.tgz", - "integrity": "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/graphql": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.3.tgz", - "integrity": "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==", - "license": "MIT", - "dependencies": { - "@octokit/request": "^10.0.6", - "@octokit/types": "^16.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", - "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", - "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", - "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", - "license": "MIT", - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", - "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" - } - }, - "node_modules/@octokit/request": { - "version": "10.0.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.8.tgz", - "integrity": "sha512-SJZNwY9pur9Agf7l87ywFi14W+Hd9Jg6Ifivsd33+/bGUQIjNujdFiXII2/qSlN2ybqUHfp5xpekMEjIBTjlSw==", - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^11.0.3", - "@octokit/request-error": "^7.0.2", - "@octokit/types": "^16.0.0", - "fast-content-type-parse": "^3.0.0", - "json-with-bigint": "^3.5.3", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/request-error": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.0.tgz", - "integrity": "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==", - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/rest": { - "version": "22.0.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz", - "integrity": "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==", - "license": "MIT", - "dependencies": { - "@octokit/core": "^7.0.6", - "@octokit/plugin-paginate-rest": "^14.0.0", - "@octokit/plugin-request-log": "^6.0.0", - "@octokit/plugin-rest-endpoint-methods": "^17.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/types": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", - "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^27.0.0" - } - }, - "node_modules/before-after-hook": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", - "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", - "license": "Apache-2.0" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/fast-content-type-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz", - "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "MIT" - }, - "node_modules/json-with-bigint": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.3.tgz", - "integrity": "sha512-QObKu6nxy7NsxqR0VK4rkXnsNr5L9ElJaGEg+ucJ6J7/suoKZ0n+p76cu9aCqowytxEbwYNzvrMerfMkXneF5A==", - "license": "MIT" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/simple-git": { - "version": "3.32.2", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.32.2.tgz", - "integrity": "sha512-n/jhNmvYh8dwyfR6idSfpXrFazuyd57jwNMzgjGnKZV/1lTh0HKvPq20v4AQ62rP+l19bWjjXPTCdGHMt0AdrQ==", - "license": "MIT", - "dependencies": { - "@kwsites/file-exists": "^1.1.1", - "@kwsites/promise-deferred": "^1.1.1", - "debug": "^4.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/steveukx/git-js?sponsor=1" - } - }, - "node_modules/universal-user-agent": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", - "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", - "license": "ISC" - } - } -} diff --git a/.github/scripts/package.json b/.github/scripts/package.json deleted file mode 100644 index 136a96bc..00000000 --- a/.github/scripts/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "type": "module", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "simple-git": "^3.32.2", - "@octokit/rest": "^22.0.1" - } -} diff --git a/.github/scripts/release-native-template.mjs b/.github/scripts/release-native-template.mjs deleted file mode 100644 index 8b672a9b..00000000 --- a/.github/scripts/release-native-template.mjs +++ /dev/null @@ -1,202 +0,0 @@ -import fs from "fs"; -import os from "os"; -import path from "path"; -import { Octokit } from "@octokit/rest"; -import { fileURLToPath } from "url"; -import simpleGit from "simple-git"; - -const required = [ - "MENDIX_MOBILE_DOCS_PR_GITHUB_PAT", - "NATIVE_TEMPLATE_VERSION_BUMP_TYPE", -]; - -const missing = required.filter((k) => !process.env[k]); -if (missing.length) { - console.error("Missing env vars:", missing.join(", ")); - process.exit(1); -} - -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const DOCS_CLONE_PREFIX = "mendix-docs-"; - -const NATIVE_TEMPLATE_VERSION_BUMP_TYPE = - process.env.NATIVE_TEMPLATE_VERSION_BUMP_TYPE; // patch, minor, major - -const MENDIX_MOBILE_DOCS_PR_GITHUB_PAT = - process.env.MENDIX_MOBILE_DOCS_PR_GITHUB_PAT; - -const NATIVE_TEMPLATE_VERSION = determineVersionFromBumpType( - NATIVE_TEMPLATE_VERSION_BUMP_TYPE, -); - -const GIT_AUTHOR_NAME = "MendixMobile"; -const GIT_AUTHOR_EMAIL = "moo@mendix.com"; - -// Docs Repo Settings -const DOCS_REPO_NAME = "docs"; -const DOCS_REPO_OWNER = "MendixMobile"; -const DOCS_UPSTREAM_OWNER = "mendix"; -const DOCS_BRANCH_NAME = `update-native-template-release-notes-v${NATIVE_TEMPLATE_VERSION}`; - -const TARGET_FILE = - "content/en/docs/releasenotes/mobile/native-template/nt-studio-pro-10-parent/nt-14-rn.md"; -// Other options: -// - content/en/docs/releasenotes/mobile/native-template/nt-studio-pro-11-parent/nt-15-rn.md -// - content/en/docs/releasenotes/mobile/native-template/nt-studio-pro-11-parent/nt-16-rn.md -// - content/en/docs/releasenotes/mobile/native-template/nt-studio-pro-11-parent/nt-17-rn.md - -const octokit = new Octokit({ auth: MENDIX_MOBILE_DOCS_PR_GITHUB_PAT }); - -function extractUnreleasedChangelog() { - const changelogPath = path.resolve( - path.join(__dirname, "..", "..", "CHANGELOG.md"), - ); - const changelog = fs.readFileSync(changelogPath, "utf-8"); - const unreleasedRegex = - /^## \[Unreleased\](.*?)(?=^## \[\d+\.\d+\.\d+\][^\n]*|\Z)/ms; - const match = changelog.match(unreleasedRegex); - if (!match) throw new Error("No [Unreleased] section found!"); - const unreleasedContent = match[1].trim(); - if (!unreleasedContent) throw new Error("No changes under [Unreleased]!"); - return unreleasedContent; -} - -// Docs -function injectUnreleasedToDoc(docPath, unreleasedContent) { - const doc = fs.readFileSync(docPath, "utf-8"); - const frontmatterMatch = doc.match(/^---[\s\S]*?---/); - if (!frontmatterMatch) throw new Error("Frontmatter not found!"); - const frontmatter = frontmatterMatch[0]; - const rest = doc.slice(frontmatter.length).trimStart(); - - const firstReleaseHeadingIndex = rest.search(/^##\s+\d+\.\d+\.\d+/m); - const beforeReleases = - firstReleaseHeadingIndex > 0 - ? `${rest.slice(0, firstReleaseHeadingIndex).trimEnd()}\n\n` - : ""; - const releaseSections = - firstReleaseHeadingIndex >= 0 - ? rest.slice(firstReleaseHeadingIndex).trimStart() - : rest.trimStart(); - - const date = new Date(); - const formattedDate = date.toLocaleDateString("en-US", { - year: "numeric", - month: "short", - day: "numeric", - }); - const title = `## ${NATIVE_TEMPLATE_VERSION}\n\n**Release date: ${formattedDate}**`; - - return `${frontmatter}\n\n${beforeReleases}${title}\n\n${unreleasedContent}\n\n${releaseSections}`; -} - -// This file exists only in the fork (MendixMobile/docs) and not in upstream (mendix/docs). -// Removing it in our branch ensures it doesn't appear in the cross-fork PR diff. -const FORK_SYNC_FILE = ".github/workflows/sync.yml"; - -async function cloneDocsRepo() { - const git = simpleGit(); - const docsCloneDir = fs.mkdtempSync( - path.join(os.tmpdir(), DOCS_CLONE_PREFIX), - ); - - await git.clone( - `https://x-access-token:${MENDIX_MOBILE_DOCS_PR_GITHUB_PAT}@github.com/${DOCS_REPO_OWNER}/${DOCS_REPO_NAME}.git`, - docsCloneDir, - ["--depth", "1"], - ); - - process.chdir(docsCloneDir); - - await git.addConfig("user.name", GIT_AUTHOR_NAME, false, "global"); - await git.addConfig("user.email", GIT_AUTHOR_EMAIL, false, "global"); -} - -async function checkoutLocalBranch(git) { - await git.checkoutLocalBranch(DOCS_BRANCH_NAME); -} - -async function updateDocsNTReleaseNotes(unreleasedContent) { - const newDocContent = injectUnreleasedToDoc(TARGET_FILE, unreleasedContent); - fs.writeFileSync(TARGET_FILE, newDocContent, "utf-8"); -} - -async function createPRUpdateDocsNTReleaseNotes(git) { - // Remove the fork's sync.yml so it doesn't appear in the cross-fork PR diff. - if (fs.existsSync(FORK_SYNC_FILE)) { - await git.rm(FORK_SYNC_FILE); - } - await git.add(TARGET_FILE); - await git.commit( - `docs: update mobile release notes for v${NATIVE_TEMPLATE_VERSION}`, - ); - await git.push("origin", DOCS_BRANCH_NAME, ["--force"]); - - const prBody = ` -Automated sync of the latest release notes for v${NATIVE_TEMPLATE_VERSION} from [native-template](https://github.com/mendix/native-template). - ---- - -**Note:** -This pull request was automatically generated by an automation process managed by the Mobile team. -**Please do not take any action on this pull request unless it has been reviewed and approved by a member of the Mobile team.** -`; - - await octokit.pulls.create({ - owner: DOCS_UPSTREAM_OWNER, - repo: DOCS_REPO_NAME, - title: `Update mobile app release notes for v${NATIVE_TEMPLATE_VERSION}`, - head: `${DOCS_REPO_OWNER}:${DOCS_BRANCH_NAME}`, - base: "development", - body: prBody, - draft: true, - }); -} - -// Update NT Release Notes in Docs repo -async function updateNTReleaseNotes(unreleasedContent) { - try { - await cloneDocsRepo(); - const git = simpleGit(); - await checkoutLocalBranch(git); - updateDocsNTReleaseNotes(unreleasedContent); - await createPRUpdateDocsNTReleaseNotes(git); - } catch (err) { - console.error("❌ Updating NT Release Notes failed:", err); - process.exit(1); - } -} - -function determineVersionFromBumpType(bumpType = "patch") { - const packageJsonPath = path.resolve( - path.join(__dirname, "..", "..", "package.json"), - ); - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")); - const currentVersion = packageJson.version; - - const [major, minor, patch] = currentVersion.split(".").map(Number); - let newVersion; - switch (bumpType) { - case "major": - newVersion = `${major + 1}.0.0`; - break; - case "minor": - newVersion = `${major}.${minor + 1}.0`; - break; - case "patch": - newVersion = `${major}.${minor}.${patch + 1}`; - break; - default: - throw new Error( - `Invalid bump type for docs release notes: ${bumpType}. Expected one of: patch, minor, major.`, - ); - } - return newVersion; -} - -(async () => { - const unreleasedContent = extractUnreleasedChangelog(); - - await updateNTReleaseNotes(unreleasedContent); -})(); diff --git a/.github/workflows/release-it.yml b/.github/workflows/release-it.yml index 9828e9d2..d0a15926 100644 --- a/.github/workflows/release-it.yml +++ b/.github/workflows/release-it.yml @@ -28,19 +28,7 @@ jobs: with: node-version-file: '.nvmrc' - - name: Install docs release script dependencies - if: ${{ contains(fromJSON('["patch","minor","major"]'), github.event.inputs.version) }} - run: npm ci --prefix .github/scripts - - - name: Create release notes PR in mendix/docs Github repository - if: ${{ contains(fromJSON('["patch","minor","major"]'), github.event.inputs.version) }} - env: - NATIVE_TEMPLATE_VERSION_BUMP_TYPE: ${{ github.event.inputs.version }} - MENDIX_MOBILE_DOCS_PR_GITHUB_PAT: ${{ secrets.MENDIX_MOBILE_DOCS_PR_GITHUB_PAT }} - run: node .github/scripts/release-native-template.mjs - - name: Release a new version - if: success() env: GITHUB_TOKEN: ${{ secrets.PUBLIC_REPO_ADMIN_TOKEN }} run: | diff --git a/.github/workflows/update_releases_list.yml b/.github/workflows/update_releases_list.yml index c5cf562e..45df503e 100644 --- a/.github/workflows/update_releases_list.yml +++ b/.github/workflows/update_releases_list.yml @@ -13,9 +13,9 @@ jobs: - uses: actions/checkout@v2 - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: "16" + node-version-file: '.nvmrc' - name: Fetch & Generate Releases List uses: actions/github-script@v3 @@ -57,3 +57,5 @@ jobs: A new version of Native Template has been released with updated version compatibility information. Please review the PR for more details: ${{ github.server_url }}/${{ github.repository }}/pull/${{ steps.pr.outputs.number }} + + 📝 *Reminder:* Run the <${{ github.server_url }}/${{ github.repository }}/actions/workflows/publish-changelog-to-docs.yml|Publish Changelog to Mendix Docs> workflow on *master*, selecting branch `${{ github.ref_name }}` as the source.