Skip to content

Commit

Permalink
impl and doc on deprecation
Browse files Browse the repository at this point in the history
  • Loading branch information
1fanwang committed Sep 23, 2024
1 parent e48ff5e commit 48ec3aa
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 0 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -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.
114 changes: 114 additions & 0 deletions .github/workflows/deprecation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
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: |
# Install necessary tools
sudo apt-get update && sudo apt-get install -y jq
# Set deprecation criteria
DEPRECATION_AGE_MONTHS=${{ github.event.inputs.deprecation_age_months || 12 }}
DEPRECATION_MINOR_VERSION_DIFF=${{ github.event.inputs.deprecation_minor_version_diff || 10 }}
# Get all releases
RELEASES=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
"https://api.github.com/repos/${{ github.repository }}/releases")
# Get the latest release version
LATEST_VERSION=$(echo "$RELEASES" | jq -r '.[0].tag_name' | sed 's/v//')
# Function to compare versions
version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
# Loop through releases and deprecate old ones
echo "$RELEASES" | jq -c '.[]' | while read -r release; do
VERSION=$(echo "$release" | jq -r '.tag_name' | sed 's/v//')
RELEASE_DATE=$(echo "$release" | jq -r '.published_at')
# Calculate age in months
AGE_MONTHS=$(( ($(date +%s) - $(date -d "$RELEASE_DATE" +%s)) / (30*24*60*60) ))
# Calculate version difference
IFS='.' read -ra LATEST_PARTS <<< "$LATEST_VERSION"
IFS='.' read -ra VERSION_PARTS <<< "$VERSION"
MINOR_DIFF=$((LATEST_PARTS[1] - VERSION_PARTS[1]))
if [ "$AGE_MONTHS" -ge "$DEPRECATION_AGE_MONTHS" ] && [ "$MINOR_DIFF" -ge "$DEPRECATION_MINOR_VERSION_DIFF" ]; then
if ! echo "$release" | jq -e '.name | contains("[DEPRECATED]")' > /dev/null; then
echo "Deprecating version $VERSION"
./gradlew deprecateVersion -PversionToDeprecate="$VERSION"
fi
fi
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 }}
17 changes: 17 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,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"
}
}
}
40 changes: 40 additions & 0 deletions gradle/java-publication.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}

0 comments on commit 48ec3aa

Please sign in to comment.