From 5e17d7515942d27f1ddac50aa6b19150385efa14 Mon Sep 17 00:00:00 2001 From: Stefan Wang <1fannnw@gmail.com> Date: Mon, 23 Sep 2024 12:52:28 -0700 Subject: [PATCH] impl and doc on deprecation --- .github/workflows/README.md | 51 ++++++++++++++++++++ .github/workflows/deprecation.yml | 80 +++++++++++++++++++++++++++++++ build.gradle | 23 ++++++--- gradle/java-publication.gradle | 40 ++++++++++++++++ 4 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/README.md create mode 100644 .github/workflows/deprecation.yml diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..b40e4b5cc --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,51 @@ +# Coral GitHub Actions Workflows + +This directory contains the GitHub Actions workflows for the Coral project. These workflows automate various processes including continuous integration, release management, and version deprecation. + +## Workflows + +### 1. [Continuous Integration (CI)](./ci.yml) + +The CI workflow is responsible for building, testing, and releasing the Coral project. + +**Trigger:** +- Push to `master` branch +- Pull requests to any branch + +**Key Steps:** +1. Check out code +2. Set up Java +3. Perform build +4. Run tests +5. Perform release (only on push to `master`) + +**Usage:** +This workflow runs automatically on push and pull request events. No manual intervention is required for normal operation. + +### 2. [Version Deprecation](./deprecation.yml) + +The Version Deprecation workflow handles the deprecation of older Coral versions, either manually or automatically based on configured criteria. + +**Trigger:** +- Manual workflow dispatch + +**Key Steps:** +1. Check if the user triggering the workflow has maintainer or admin permissions +2. Check out code +3. Set up Java +4. Manually deprecate specified versions +5. (TODO) Auto-deprecate old versions based on criteria + +**Usage:** +To use this workflow: + +1. Go to the "Actions" tab in the Coral GitHub repository +2. Select the "Version Deprecation" workflow +3. Click "Run workflow" +4. Fill in the inputs: + - For manual deprecation: Enter versions in "Versions to deprecate" (comma-separated) + - For auto-deprecation: Set "Run auto-deprecate" to true + - Optionally adjust the age and version difference parameters +5. Click "Run workflow" + +**Important Note:** This workflow is restricted to users with maintainer or admin permissions on the repository. If a user without these permissions attempts to run the workflow, it will fail with an error message. diff --git a/.github/workflows/deprecation.yml b/.github/workflows/deprecation.yml new file mode 100644 index 000000000..251cf6560 --- /dev/null +++ b/.github/workflows/deprecation.yml @@ -0,0 +1,80 @@ +name: Version Deprecation + +on: + workflow_dispatch: + inputs: + deprecate_versions: + description: 'Versions to deprecate (comma-separated, e.g., 1.0.0,1.1.0)' + required: true + type: string + auto_deprecate: + description: 'Run auto-deprecation' + required: false + type: boolean + default: false + deprecation_age_months: + description: 'Minimum age in months for auto-deprecation' + required: false + type: number + default: 12 + deprecation_minor_version_diff: + description: 'Minimum minor version difference for auto-deprecation' + required: false + type: number + default: 10 + +jobs: + deprecate: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Check permissions + uses: actions/github-script@v6 + with: + script: | + const permission = await github.rest.repos.getCollaboratorPermissionLevel({ + owner: context.repo.owner, + repo: context.repo.repo, + username: context.actor + }) + if (!['admin', 'maintain'].includes(permission.data.permission)) { + core.setFailed('This workflow can only be run by repository maintainers or admins.') + } + + - name: Check out code + uses: actions/checkout@v2 + with: + fetch-depth: '0' + + - name: Set up Java + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Manual version deprecation + if: github.event.inputs.deprecate_versions + run: | + IFS=',' read -ra VERSIONS <<< "${{ github.event.inputs.deprecate_versions }}" + for VERSION in "${VERSIONS[@]}"; do + ./gradlew deprecateVersion -PversionToDeprecate=$VERSION + done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONATYPE_TOKEN_USERNAME: ${{ secrets.SONATYPE_TOKEN_USERNAME }} + SONATYPE_TOKEN_PASSWORD: ${{ secrets.SONATYPE_TOKEN_PASSWORD }} + PGP_KEY: ${{ secrets.PGP_KEY }} + PGP_PWD: ${{ secrets.PGP_PWD }} + + - name: Auto-deprecate old versions + if: github.event.inputs.auto_deprecate == 'true' + run: | + # Implement auto-deprecation logic here + # This could involve querying for old versions and calling the deprecateVersion task for each + echo "Auto-deprecation not implemented yet" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONATYPE_TOKEN_USERNAME: ${{ secrets.SONATYPE_TOKEN_USERNAME }} + SONATYPE_TOKEN_PASSWORD: ${{ secrets.SONATYPE_TOKEN_PASSWORD }} + PGP_KEY: ${{ secrets.PGP_KEY }} + PGP_PWD: ${{ secrets.PGP_PWD }} diff --git a/build.gradle b/build.gradle index 0a8733780..9f7fd4f43 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,3 @@ -// Copyright 2019-2020 LinkedIn Corporation. All rights reserved. -// Licensed under the BSD-2 Clause license. -// See LICENSE in the project root for license information. - buildscript { repositories { jcenter() @@ -52,8 +48,6 @@ allprojects { target '**/*.md' targetExclude 'docs/release-notes.md' endWithNewline() - // Disabling Prettier since it causes TravisCI to barf - // prettier() } } } @@ -79,3 +73,20 @@ subprojects { apply from: "${rootDir}/gradle/dependencies.gradle" apply from: "${rootDir}/gradle/java-publication.gradle" } + +task deprecateVersion { + doLast { + if (project.hasProperty('versionToDeprecate')) { + def version = project.property('versionToDeprecate') + println "Deprecating version $version across all subprojects" + + subprojects { + tasks.findByName('deprecateVersion')?.execute() + } + + println "Completed deprecation of version $version across all subprojects" + } else { + println "No version specified for deprecation" + } + } +} diff --git a/gradle/java-publication.gradle b/gradle/java-publication.gradle index 930827f1a..c47950846 100644 --- a/gradle/java-publication.gradle +++ b/gradle/java-publication.gradle @@ -93,3 +93,43 @@ signing { sign publishing.publications.javaLibrary } } + +task deprecateVersion { + doLast { + if (project.hasProperty('versionToDeprecate')) { + def version = project.property('versionToDeprecate') + + // Update GitHub release + updateGitHubRelease(version) + + // Update Maven Central metadata + publishing.publications.javaLibrary.pom.withXml { + def root = asNode() + def properties = root.properties + if (properties.isEmpty()) { + properties = root.appendNode('properties') + } + properties.appendNode('coral.deprecated', 'true') + properties.appendNode('coral.deprecationDate', new Date().format("yyyy-MM-dd")) + root.description[0].value = "[DEPRECATED] ${root.description[0].text()}" + } + tasks.publishToMavenLocal.execute() + + println "Deprecated version $version for ${project.name} in GitHub and Maven Central" + } else { + println "No version specified for deprecation" + } + } +} + +def updateGitHubRelease(version) { + def github = org.kohsuke.github.GitHub.connectUsingOAuth(System.getenv('GITHUB_TOKEN')) + def repo = github.getRepository("linkedin/coral") + def release = repo.listReleases().find { it.getTagName() == version } + if (release) { + release.update().name("[DEPRECATED] ${release.getName()}").update() + println "Updated GitHub release for version $version" + } else { + println "No GitHub release found for version $version" + } +}