diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml new file mode 100644 index 0000000..441594c --- /dev/null +++ b/.github/workflows/create-release.yml @@ -0,0 +1,52 @@ +name: Create release PR +on: + workflow_dispatch: + inputs: + version: + description: 'New version' + required: true + type: string +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + strategy: + matrix: + node-version: [20] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + steps: + - name: Create app token + uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.THEOPLAYER_BOT_APP_ID }} + private-key: ${{ secrets.THEOPLAYER_BOT_PRIVATE_KEY }} + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ steps.app-token.outputs.token }} + - name: Configure Git user + run: | + git config user.name 'theoplayer-bot[bot]' + git config user.email '873105+theoplayer-bot[bot]@users.noreply.github.com' + - name: Bump version + shell: bash + run: | + node ./scripts/set_version.js ${{ inputs.version }} + - name: Push to release branch + shell: bash + run: | + git commit -a -m ${{ inputs.version }} + git push origin "HEAD:release/${{ inputs.version }}" + - name: Create pull request + shell: bash + run: | + gh pr create \ + --base main \ + --head "release/${{ inputs.version }}" \ + --title "Release ${{ inputs.version }}" \ + --body "$(node ./scripts/github_changelog.js ${{ inputs.version }})" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 42df235..fecd023 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,22 +1,39 @@ name: Publish release on: - # Runs whenever a new release is created in GitHub - release: - types: [ created ] + # Runs whenever a release PR is merged + pull_request: + branches: + - main + types: [ closed ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: jobs: # Publish job publish: + # Run only for "release/x.y.z" PRs, and only when the PR is merged (not abandoned) + if: ${{ !github.event.pull_request || (startsWith(github.head_ref, 'release/') && github.event.pull_request.merged) }} runs-on: ubuntu-latest # Sets permissions of the GITHUB_TOKEN to allow publishing to GitHub Packages permissions: - contents: read + contents: write packages: write + id-token: write steps: + - name: Create app token + uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.THEOPLAYER_BOT_APP_ID }} + private-key: ${{ secrets.THEOPLAYER_BOT_PRIVATE_KEY }} - name: Checkout uses: actions/checkout@v4 + with: + token: ${{ steps.app-token.outputs.token }} + - name: Configure Git user + run: | + git config user.name 'theoplayer-bot[bot]' + git config user.email '873105+theoplayer-bot[bot]@users.noreply.github.com' - name: Setup Java uses: actions/setup-java@v4 with: @@ -32,3 +49,18 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} REPOSILITE_USERNAME: ${{ secrets.REPOSILITE_USERNAME }} REPOSILITE_PASSWORD: ${{ secrets.REPOSILITE_PASSWORD }} + - name: Get version + shell: bash + run: | + echo "version=$(./gradlew :ui:properties --no-daemon --console=plain --quiet | awk '/^version:/ {print $2}')" >> "$GITHUB_ENV" + - name: Push tag + run: | + git tag "v$version" -m "$version" + git push origin "v$version" + - name: Create GitHub release + run: | + gh release create "v$version" --verify-tag --latest \ + --title "$version" \ + --notes "$(node ./scripts/github_changelog.js $version)" + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/sync-develop.yml b/.github/workflows/sync-develop.yml new file mode 100644 index 0000000..1c8d03b --- /dev/null +++ b/.github/workflows/sync-develop.yml @@ -0,0 +1,31 @@ +name: Sync develop with main +on: + push: + branches: + - main + workflow_dispatch: +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Create app token + uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.THEOPLAYER_BOT_APP_ID }} + private-key: ${{ secrets.THEOPLAYER_BOT_PRIVATE_KEY }} + - name: Checkout + uses: actions/checkout@v4 + with: + token: ${{ steps.app-token.outputs.token }} + ref: develop + fetch-depth: 50 + - name: Configure Git user + run: | + git config user.name 'theoplayer-bot[bot]' + git config user.email '873105+theoplayer-bot[bot]@users.noreply.github.com' + - name: Sync develop with main + run: | + git fetch --no-tags --prune --no-recurse-submodules --depth=50 origin +refs/heads/main:refs/remotes/origin/main + git merge --ff origin/main + git push origin HEAD:develop diff --git a/gradle.properties b/gradle.properties index 9f771bf..adb4f0b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,4 +24,4 @@ android.nonTransitiveRClass=true android.nonFinalResIds=true org.gradle.configuration-cache=true # The version of the THEOplayer Open Video UI for Android. -libraryVersion=1.8.0 +version=1.8.0 diff --git a/scripts/github_changelog.js b/scripts/github_changelog.js new file mode 100755 index 0000000..fb2b2e5 --- /dev/null +++ b/scripts/github_changelog.js @@ -0,0 +1,23 @@ +#!/usr/bin/env node +const fs = require("node:fs"); +const path = require("node:path"); +const version = process.argv[2]; +if (!version) { + console.error("Missing required argument: version"); + process.exit(1); +} + +// Find block with current version +const changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); +const changelog = fs.readFileSync(changelogPath, "utf-8"); +const headingStart = "## "; +// Find block with current version +const block = changelog + .split(headingStart) + .find((block) => block.startsWith(`v${version}`)) + .trim(); +let lines = block.split("\n"); +// Remove version +lines.splice(0, 1); + +console.log(lines.join("\n").trim()); diff --git a/scripts/set_version.js b/scripts/set_version.js new file mode 100755 index 0000000..4f33e5f --- /dev/null +++ b/scripts/set_version.js @@ -0,0 +1,30 @@ +#!/usr/bin/env node +const fs = require("node:fs"); +const path = require("node:path"); +const version = process.argv[2]; +if (!version) { + console.error("Missing required argument: version"); + process.exit(1); +} + +// Update "version=1.2.3" in gradle.properties +const gradlePropertiesPath = path.resolve(__dirname, "../gradle.properties"); +let gradleProperties = fs.readFileSync(gradlePropertiesPath, "utf8"); +gradleProperties = gradleProperties.replace( + /^version=.+$/m, + `version=${version}` +); +fs.writeFileSync(gradlePropertiesPath, gradleProperties); + +// Update heading in CHANGELOG.md +const changelogPath = path.resolve(__dirname, "../CHANGELOG.md"); +let changelog = fs.readFileSync(changelogPath, "utf8"); +const now = new Date(); +const today = `${now.getFullYear()}-${(now.getMonth() + 1) + .toString() + .padStart(2, "0")}-${now.getDate().toString().padStart(2, "0")}`; +changelog = changelog.replace( + /^## Unreleased$/m, + `## ${version} (${today})` +); +fs.writeFileSync(changelogPath, changelog); diff --git a/ui/build.gradle.kts b/ui/build.gradle.kts index d7b1d12..3d3877f 100644 --- a/ui/build.gradle.kts +++ b/ui/build.gradle.kts @@ -123,10 +123,9 @@ publishing { publications { register("release") { - val libraryVersion: String by rootProject.extra groupId = "com.theoplayer.android-ui" artifactId = "android-ui" - version = libraryVersion + version = project.version as String artifact(dokkaJavadocJar) afterEvaluate { from(components["release"])