diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d59e4c488..b43a0bfc3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,8 +13,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - with: - lfs: true + with: + fetch-depth: 100 - uses: actions/setup-node@v6 with: node-version: 'lts/*' @@ -31,8 +31,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - with: - lfs: true + with: + fetch-depth: 100 - uses: actions/setup-node@v6 with: node-version: 'lts/*' @@ -56,8 +56,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - with: - lfs: true + with: + fetch-depth: 100 - uses: actions/setup-node@v6 with: node-version: 'lts/*' @@ -80,19 +80,10 @@ jobs: build_kotlin: name: Build and Test Kotlin runs-on: ubuntu-latest - env: - OSSRH_USERNAME: ${{secrets.OSSRH_USERNAME}} - OSSRH_PASSWORD: ${{secrets.OSSRH_PASSWORD}} - OSSRH_USERTOKEN_USERNAME: ${{secrets.OSSRH_USERTOKEN_USERNAME}} - OSSRH_USERTOKEN_PASSWORD: ${{secrets.OSSRH_USERTOKEN_PASSWORD}} - SONATYPE_STAGING_PROFILE_ID: ${{secrets.SONATYPE_STAGING_PROFILE_ID}} - SONATYPE_SIGNING_KEY_ID: ${{secrets.SONATYPE_SIGNING_KEY_ID}} - SONATYPE_SIGNING_PASSWORD: ${{secrets.SONATYPE_SIGNING_PASSWORD}} - SONATYPE_SIGNING_KEY: ${{secrets.SONATYPE_SIGNING_KEY}} steps: - uses: actions/checkout@v6 - with: - lfs: true + with: + fetch-depth: 100 - uses: actions/setup-node@v6 with: node-version: 'lts/*' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 441cf161d..9e2f8a23c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -6,139 +6,21 @@ on: workflow_dispatch: jobs: - check_sha: - name: check_sha - runs-on: ubuntu-latest - outputs: - hit: ${{ steps.cache.outputs.cache-hit == 'true' }} - steps: - - run: touch dummy.txt - - - uses: actions/cache@v5 - id: cache - with: - path: dummy.txt - key: check-sha-${{ github.sha }} - - nighty_web: - name: Web - needs: check_sha - if: needs.check_sha.outputs.hit == 'false' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - lfs: true - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - cache: 'npm' - - - run: npm run update-version -- alpha ${{github.run_number}} - - run: npm ci - - run: npm run build-web - - run: npm run build-language-server - - run: npm run build-monaco - - run: npm pack - working-directory: ./packages/alphatab/ - - run: npm pack - working-directory: ./packages/vite/ - - run: npm pack - working-directory: ./packages/webpack/ - - run: npm pack - working-directory: ./packages/lsp/ - - run: npm pack - working-directory: ./packages/monaco/ - - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - registry-url: https://registry.npmjs.org/ - - - run: npm publish --access public --tag alpha - working-directory: ./packages/alphatab/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - - run: npm publish --access public --tag alpha - working-directory: ./packages/vite/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - - run: npm publish --access public --tag alpha - working-directory: ./packages/webpack/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - - run: npm publish --access public --tag alpha - working-directory: ./packages/lsp/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - - run: npm publish --access public --tag alpha - working-directory: ./packages/monaco/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - nightly_csharp: - name: C# - needs: check_sha - if: needs.check_sha.outputs.hit == 'false' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - lfs: true - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - cache: 'npm' - - - uses: actions/setup-dotnet@v5 - with: - dotnet-version: "8" - - - run: npm run update-version -- alpha ${{github.run_number}} - - run: npm ci - - run: npm run build-csharp - - - run: dotnet nuget push AlphaTab/bin/Release/*.nupkg -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json - working-directory: ./packages/csharp/src/ - - run: dotnet nuget push AlphaTab.Windows/bin/Release/*.nupkg -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json - working-directory: ./packages/csharp/src/ - - nightly_kotlin_android: - name: Kotlin (Android) - needs: check_sha - if: needs.check_sha.outputs.hit == 'false' - runs-on: ubuntu-latest - env: - ORG_GRADLE_PROJECT_mavenCentralUsername: ${{secrets.OSSRH_USERTOKEN_USERNAME}} - ORG_GRADLE_PROJECT_mavenCentralPassword: ${{secrets.OSSRH_USERTOKEN_PASSWORD}} - ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{secrets.SONATYPE_SIGNING_KEY_ID}} - ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{secrets.SONATYPE_SIGNING_PASSWORD}} - ORG_GRADLE_PROJECT_signingInMemoryKey: ${{secrets.SONATYPE_SIGNING_KEY}} - steps: - - uses: actions/checkout@v6 - with: - lfs: true - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - cache: 'npm' - - - uses: actions/setup-java@v5 - with: - java-version: "19" - distribution: "temurin" - - - run: npm run update-version -- alpha ${{github.run_number}} - - run: npm ci - - run: npm run build-kotlin - - - run: ./gradlew publishToMavenCentral - working-directory: ./packages/kotlin/src/ - - - run: ./gradlew --stop - working-directory: ./packages/kotlin/src/ - + web: + uses: ./.github/workflows/~publish_web.yml + secrets: inherit + with: + version: alpha ${{github.run_number}} + npm_tag: alpha + + dotnet: + uses: ./.github/workflows/~publish_dotnet.yml + secrets: inherit + with: + version: alpha ${{github.run_number}} + + kotlin: + uses: ./.github/workflows/~publish_kotlin.yml + secrets: inherit + with: + version: alpha ${{github.run_number}} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cad9beecc..44492ba0f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,116 +19,27 @@ on: default: true jobs: - release_web: - name: Web - runs-on: ubuntu-latest + web: + uses: ./.github/workflows/~publish_web.yml + secrets: inherit if: (github.event_name == 'push') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_web == 'true') - steps: - - uses: actions/checkout@v6 - with: - lfs: true - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - - - run: npm run update-version -- ${{github.run_number}} - - run: npm ci - - run: npm run build-web - - run: npm run build-language-server - - run: npm run build-monaco - - run: npm pack - working-directory: ./packages/alphatab/ - - run: npm pack - working-directory: ./packages/vite/ - - run: npm pack - working-directory: ./packages/webpack/ - - run: npm pack - working-directory: ./packages/lsp/ - - run: npm pack - working-directory: ./packages/monaco/ - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - registry-url: https://registry.npmjs.org/ - - name: Publish to NPM (alphaTab release) - run: npm publish --access public - working-directory: ./packages/alphatab/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - name: Publish to NPM (Vite Plugin release) - run: npm publish --access public - working-directory: ./packages/vite/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - name: Publish to NPM (Webpack release) - run: npm publish --access public - working-directory: ./packages/webpack/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - name: Publish to NPM (Language Server release) - run: npm publish --access public - working-directory: ./packages/lsp/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - name: Publish to NPM (Monaco release) - run: npm publish --access public - working-directory: ./packages/monaco/ - env: - NODE_AUTH_TOKEN: ${{secrets.NPMJS_AUTH_TOKEN}} - - release_csharp: - name: C# - runs-on: ubuntu-latest + with: + version: ${{github.run_number}} + npm_tag: latest + force: true + + dotnet: + uses: ./.github/workflows/~publish_dotnet.yml + secrets: inherit if: (github.event_name == 'push') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_csharp == 'true') - steps: - - uses: actions/checkout@v6 - with: - lfs: true - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - - uses: actions/setup-dotnet@v5 - with: - dotnet-version: '8' - env: - NUGET_AUTH_TOKEN: ${{secrets.NUGET_API_KEY}} - - run: npm run update-version -- ${{github.run_number}} - - run: npm ci - - run: npm run build-csharp - - run: dotnet nuget push AlphaTab/bin/Release/*.nupkg -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json --skip-duplicate - working-directory: ./packages/csharp/src/ - - run: dotnet nuget push AlphaTab.Windows/bin/Release/*.nupkg -k ${{secrets.NUGET_API_KEY}} -s https://api.nuget.org/v3/index.json --skip-duplicate - working-directory: ./packages/csharp/src/ + with: + version: ${{github.run_number}} + force: true - release_kotlin_android: - name: Kotlin (Android) - runs-on: windows-latest + kotlin: + uses: ./.github/workflows/~publish_kotlin.yml + secrets: inherit if: (github.event_name == 'push') || (github.event_name == 'workflow_dispatch' && github.event.inputs.release_kotlin_android == 'true') - env: - ORG_GRADLE_PROJECT_mavenCentralUsername: ${{secrets.OSSRH_USERTOKEN_USERNAME}} - ORG_GRADLE_PROJECT_mavenCentralPassword: ${{secrets.OSSRH_USERTOKEN_PASSWORD}} - ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{secrets.SONATYPE_SIGNING_KEY_ID}} - ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{secrets.SONATYPE_SIGNING_PASSWORD}} - ORG_GRADLE_PROJECT_signingInMemoryKey: ${{secrets.SONATYPE_SIGNING_KEY}} - steps: - - uses: actions/checkout@v6 - with: - lfs: true - - uses: actions/setup-node@v6 - with: - node-version: 'lts/*' - - - uses: actions/setup-java@v5 - with: - java-version: "19" - distribution: "temurin" - - - run: npm run update-version -- ${{github.run_number}} - - run: npm ci - - run: npm run build-kotlin - - run: ./gradlew publishToMavenCentral - working-directory: ./packages/kotlin/src/ - - - run: ./gradlew --stop - working-directory: ./packages/kotlin/src/ - + with: + version: ${{github.run_number}} + force: true \ No newline at end of file diff --git a/.github/workflows/~publish_dotnet.yml b/.github/workflows/~publish_dotnet.yml new file mode 100644 index 000000000..5655bc8f8 --- /dev/null +++ b/.github/workflows/~publish_dotnet.yml @@ -0,0 +1,50 @@ +on: + workflow_call: + inputs: + version: + type: string + required: true + force: + type: boolean + default: false + +jobs: + check: + runs-on: ubuntu-latest + outputs: + has_changes: ${{ steps.check.outputs.has_changes }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 100 + - uses: actions/setup-node@v6 + with: + node-version: 'lts/*' + cache: 'npm' + - run: npm run nightly-check -- --platform dotnet --force ${{ inputs.force }} + id: check + + build: + needs: check + if: needs.check.outputs.has_changes == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 100 + - uses: actions/setup-node@v6 + with: + node-version: 'lts/*' + cache: 'npm' + - uses: actions/setup-dotnet@v5 + with: + dotnet-version: "8" + + - run: npm run update-version -- ${{inputs.version}} + - run: npm ci + - run: npm run build-csharp + + - run: npm run nightly-pack -- --platform dotnet --force ${{ inputs.force }} + - run: npm run nightly-publish -- --platform dotnet --force ${{ inputs.force }} + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} diff --git a/.github/workflows/~publish_kotlin.yml b/.github/workflows/~publish_kotlin.yml new file mode 100644 index 000000000..25bc40a78 --- /dev/null +++ b/.github/workflows/~publish_kotlin.yml @@ -0,0 +1,55 @@ +on: + workflow_call: + inputs: + version: + type: string + required: true + force: + type: boolean + default: false + +jobs: + check: + runs-on: ubuntu-latest + outputs: + has_changes: ${{ steps.check.outputs.has_changes }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 100 + - uses: actions/setup-node@v6 + with: + node-version: 'lts/*' + cache: 'npm' + - run: npm run nightly-check -- --platform kotlin --force ${{ inputs.force }} + id: check + + build: + needs: check + if: needs.check.outputs.has_changes == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 100 + - uses: actions/setup-node@v6 + with: + node-version: 'lts/*' + cache: 'npm' + - uses: actions/setup-java@v5 + with: + java-version: "19" + distribution: "temurin" + + - run: npm run update-version -- ${{inputs.version}} + - run: npm ci + - run: npm run build-kotlin + + - run: npm run nightly-pack -- --platform kotlin --force ${{ inputs.force }} + - run: npm run nightly-publish -- --platform kotlin --force ${{ inputs.force }} + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{secrets.OSSRH_USERTOKEN_USERNAME}} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{secrets.OSSRH_USERTOKEN_PASSWORD}} + ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{secrets.SONATYPE_SIGNING_KEY_ID}} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{secrets.SONATYPE_SIGNING_PASSWORD}} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{secrets.SONATYPE_SIGNING_KEY}} diff --git a/.github/workflows/~publish_web.yml b/.github/workflows/~publish_web.yml new file mode 100644 index 000000000..4b79f8d0b --- /dev/null +++ b/.github/workflows/~publish_web.yml @@ -0,0 +1,54 @@ +on: + workflow_call: + inputs: + version: + type: string + required: true + force: + type: boolean + default: false + npm_tag: + type: string + required: true + + +jobs: + check: + runs-on: ubuntu-latest + outputs: + has_changes: ${{ steps.check.outputs.has_changes }} + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 100 + - uses: actions/setup-node@v6 + with: + node-version: 'lts/*' + cache: 'npm' + - run: npm run nightly-check -- --platform web --force ${{ inputs.force }} + id: check + + build: + needs: check + if: needs.check.outputs.has_changes == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 100 + - uses: actions/setup-node@v6 + with: + node-version: 'lts/*' + cache: 'npm' + registry-url: https://registry.npmjs.org/ + + - run: npm run update-version -- ${{inputs.version}} + - run: npm ci + - run: npm run build-web + - run: npm run build-language-server + - run: npm run build-monaco + + - run: npm run nightly-pack -- --platform web --force ${{ inputs.force }} + - run: npm run nightly-publish -- --platform web --force ${{ inputs.force }} --tag ${{ inputs.npm_tag }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPMJS_AUTH_TOKEN }} diff --git a/package-lock.json b/package-lock.json index 9e488fd0c..7290c26c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@coderline/alphatab-monorepo", - "version": "1.8.0", + "version": "1.9.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@coderline/alphatab-monorepo", - "version": "1.8.0", + "version": "1.9.0", "workspaces": [ "packages/*" ], @@ -6914,7 +6914,7 @@ }, "packages/alphatab": { "name": "@coderline/alphatab", - "version": "1.8.0", + "version": "1.9.0", "license": "MPL-2.0", "devDependencies": { "@biomejs/biome": "^2.3.11", @@ -6942,7 +6942,7 @@ }, "packages/alphatex": { "name": "@coderline/alphatab-alphatex", - "version": "1.8.0", + "version": "1.9.0", "devDependencies": { "rimraf": "^6.1.2", "tslib": "^2.8.1", @@ -6952,7 +6952,7 @@ }, "packages/csharp": { "name": "@coderline/alphatab-csharp", - "version": "1.8.0", + "version": "1.9.0", "devDependencies": { "@coderline/alphatab-transpiler": "*", "rimraf": "^6.1.2" @@ -6960,14 +6960,14 @@ }, "packages/kotlin": { "name": "@coderline/alphatab-kotlin", - "version": "1.8.0" + "version": "1.9.0" }, "packages/lsp": { "name": "@coderline/alphatab-language-server", - "version": "1.8.0", + "version": "1.9.0", "license": "MPL-2.0", "dependencies": { - "@coderline/alphatab": "^1.8.0", + "@coderline/alphatab": "^1.9.0", "vscode-languageserver": "^9.0.1", "vscode-languageserver-textdocument": "^1.0.12" }, @@ -6991,11 +6991,11 @@ }, "packages/monaco": { "name": "@coderline/alphatab-monaco", - "version": "1.8.0", + "version": "1.9.0", "license": "MPL-2.0", "dependencies": { - "@coderline/alphatab": "^1.8.0", - "@coderline/alphatab-language-server": "^1.8.0", + "@coderline/alphatab": "^1.9.0", + "@coderline/alphatab-language-server": "^1.9.0", "monaco-editor": "^0.55.1", "vscode-languageserver-types": "^3.17.5", "vscode-oniguruma": "^2.0.1", @@ -7021,7 +7021,7 @@ }, "packages/playground": { "name": "@coderline/alphatab-playground", - "version": "1.8.0", + "version": "1.9.0", "dependencies": { "@coderline/alphatab": "*", "@fontsource/noto-sans": "^5.2.10", @@ -7045,7 +7045,7 @@ }, "packages/tooling": { "name": "@coderline/alphatab-tooling", - "version": "1.8.0", + "version": "1.9.0", "devDependencies": { "@microsoft/api-extractor": "^7.55.2", "@rollup/plugin-terser": "^0.4.4", @@ -7056,11 +7056,11 @@ }, "packages/transpiler": { "name": "@coderline/alphatab-transpiler", - "version": "1.8.0" + "version": "1.9.0" }, "packages/vite": { "name": "@coderline/alphatab-vite", - "version": "1.8.0", + "version": "1.9.0", "license": "MPL-2.0", "dependencies": { "magic-string": "^0.30.21", @@ -7088,7 +7088,7 @@ }, "packages/vscode": { "name": "alphatab-vscode", - "version": "1.8.0", + "version": "1.9.0", "license": "MPL-2.0", "devDependencies": { "@biomejs/biome": "^2.3.11", @@ -7115,7 +7115,7 @@ }, "packages/webpack": { "name": "@coderline/alphatab-webpack", - "version": "1.8.0", + "version": "1.9.0", "license": "MPL-2.0", "dependencies": { "webpack": "^5.104.1" diff --git a/package.json b/package.json index 7118a5914..9026be2d0 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,11 @@ "build-webpack": "npm run build --workspace=packages/webpack", "test-webpack": "npm run test --workspace=packages/webpack", - "build-monaco": "npm run build --workspace=packages/monaco" + "build-monaco": "npm run build --workspace=packages/monaco", + + "nightly-check": "node ./scripts/nightly.mts --mode check", + "nightly-pack": "node ./scripts/nightly.mts --mode pack", + "nightly-publish": "node ./scripts/nightly.mts --mode publish" }, "devDependencies": { "concurrently": "^9.2.1" diff --git a/scripts/nightly.mts b/scripts/nightly.mts new file mode 100644 index 000000000..6a19a2c39 --- /dev/null +++ b/scripts/nightly.mts @@ -0,0 +1,190 @@ +import { type ExecSyncOptionsWithBufferEncoding, execSync } from 'node:child_process'; +import { appendFileSync, existsSync, readdirSync, readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import { exit } from 'node:process'; +import { type ParseArgsOptionsConfig, parseArgs } from 'node:util'; + +const options: ParseArgsOptionsConfig = { + platform: { + type: 'string' + }, + mode: { + type: 'string' + }, + force: { + type: 'string' + }, + tag: { + type: 'string' + } +}; + +function getChangedPackages(force: boolean) { + const packages = new Set(); + if (!force) { + // get all commits since 26 hours + const featureCommits = execSync( + "git log --since='26 hours ago' --pretty=format:'%H;%an <%ae>' --perl-regexp --author='^((?!dependabot).*)$'", + { + encoding: 'utf-8' + } + ) + .split('\n') + .map(l => { + const p = l.split(';'); + return { hash: p[0], author: p[1] }; + }); + + console.info('Detected following feature commits', featureCommits); + if (featureCommits.length === 0) { + console.info('No feature commits, no packages changed'); + return packages; + } + + // translate commits to changed packages + for (const commit of featureCommits) { + const files = execSync(`git show --name-only ${commit.hash} --pretty=""`, { + encoding: 'utf-8' + }).split('\n'); + + for (const file of files) { + const packageName = file.split('/')[1]; + if (packageName) { + packages.add(packageName); + } + } + } + } else { + for (const pkg of readdirSync(resolve(import.meta.dirname, '../packages/'), { withFileTypes: true })) { + if (pkg.isDirectory()) { + packages.add(pkg.name); + } + } + } + + for (const packageName of Array.from(packages)) { + const packageJson = resolve(import.meta.dirname, '../packages/', packageName, 'package.json'); + if (!existsSync(packageJson)) { + packages.delete(packageName); + continue; + } + + const isPrivate = JSON.parse(readFileSync(packageJson, 'utf-8')).private; + if (isPrivate) { + packages.delete(packageName); + } + } + + console.info('Detected following changed packages', packages); + return packages; +} + +const DRY_RUN = process.env.DRY_RUN; +function execDryRun(command: string, options: ExecSyncOptionsWithBufferEncoding) { + console.info(`executing command ${command} in ${options.cwd}`); + if (DRY_RUN) { + console.warn('nothing executed, dry run active'); + } else { + execSync(command, options); + } +} + +function publish(platform: string, packages: Set) { + switch (platform) { + case 'web': + for (const packageName of packages) { + execDryRun(`npm publish --access public --tag ${args.tag}`, { + stdio: 'inherit', + cwd: resolve(import.meta.dirname, '../packages', packageName) + }); + } + break; + case 'dotnet': + const dotnetPackages = ['AlphaTab', 'AlphaTab.Windows']; + for (const pkg of dotnetPackages) { + execDryRun( + `dotnet nuget push ${pkg}/bin/Release/*.nupkg -k ${process.env.NUGET_API_KEY} -s https://api.nuget.org/v3/index.json`, + { + stdio: 'inherit', + cwd: resolve(import.meta.dirname, '../packages/csharp/src') + } + ); + } + break; + case 'kotlin': + execDryRun(`./gradlew publishToMavenCentral`, { + stdio: 'inherit', + cwd: resolve(import.meta.dirname, '../packages/kotlin/src/') + }); + break; + } +} + +function pack(platform: string, packages: Set) { + switch (platform) { + case 'web': + for (const packageName of packages) { + console.info('npm pack', packageName); + execSync('npm pack', { + stdio: 'inherit', + cwd: resolve(import.meta.dirname, '../packages', packageName) + }); + } + break; + case 'dotnet': + console.info('dotnet pack skipped, nupkgs are created automatically'); + break; + case 'kotlin': + console.info('kotlin pack skipped, there is no pack step'); + break; + } +} + +function check(platform: string, packages: Set) { + let hasChanges = false; + switch (platform) { + case 'web': + hasChanges = packages.size > 0; + break; + case 'dotnet': + hasChanges = packages.has('alphatab') || packages.has('csharp'); + if (!hasChanges) { + console.info('dotnet build skipped, no relevant package changed'); + } + break; + case 'kotlin': + hasChanges = packages.has('alphatab') || packages.has('kotlin'); + if (!hasChanges) { + console.info('kotlin build skipped, no relevant package changed'); + } + break; + } + + const hasChangesOutput = `has_changes=${hasChanges ? 'true' : 'false'}`; + if (process.env.GITHUB_OUTPUT) { + appendFileSync(process.env.GITHUB_OUTPUT, hasChangesOutput); + } else { + console.info(hasChangesOutput); + } +} + +const args = parseArgs({ + options, + strict: true +}).values; +const packages = getChangedPackages(args.force === 'true'); + +switch (args.mode) { + case 'pack': + pack(args.platform as string, packages); + break; + case 'publish': + publish(args.platform as string, packages); + break; + case 'check': + check(args.platform as string, packages); + break; + default: + console.error('Invalid mode', args.mode); + exit(1); +}