Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version Deprecation Features in Coral #536

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
}
}
Loading