Skip to content
Merged
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
118 changes: 117 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ on:
push:
branches:
- master
# Documentation only changes (README, badges, screenshots) do not need a build or a release
paths-ignore:
- '**.md'
- 'art/**'
pull_request:
branches:
- master
paths-ignore:
- '**.md'
- 'art/**'
workflow_dispatch: # Allows manual trigger of the workflow

permissions:
Expand All @@ -22,6 +29,7 @@ env:
TEST_JAVA_VERSION: '21'

# Stages: Resolve Version -> Test (lowest and latest Android SDK) -> Build library & sample app -> Tag & Release
# -> Publish to GitHub Packages and Maven Central
# The Test report job publishes the JUnit results of every SDK, also when the tests fail.
# Every stage must succeed for the next one to start.
jobs:
Expand Down Expand Up @@ -166,10 +174,15 @@ jobs:
echo "ANDROID_KEYSTORE_FILE=$RUNNER_TEMP/release.keystore" >> "$GITHUB_ENV"

- name: Build
env:
# Sign the Maven artifacts outside pull requests, when a key is configured
ORG_GRADLE_PROJECT_signingKey: ${{ github.event_name != 'pull_request' && secrets.SIGNING_KEY || '' }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }}
run: |
./gradlew \
:flowlayoutmanager:assembleRelease \
:flowlayoutmanager:publishToMavenLocal \
:flowlayoutmanager:publishReleasePublicationToStagingRepository \
:app:assembleDebug \
:app:assembleRelease

Expand All @@ -196,6 +209,15 @@ jobs:
path: dist/*
if-no-files-found: error

# Maven repository layout (AAR, sources, javadoc, POM and signatures),
# published as is to GitHub Packages and Maven Central
- name: Upload Maven artifacts
uses: actions/upload-artifact@v7
with:
name: maven-${{ env.VERSION }}
path: flowlayoutmanager/build/staging-deploy/
if-no-files-found: error

release:
name: Tag & Release
runs-on: ubuntu-latest
Expand All @@ -218,6 +240,12 @@ jobs:
name: flowlayoutmanager-${{ env.VERSION }}
path: release

- name: Download Maven artifacts
uses: actions/download-artifact@v8
with:
name: maven-${{ env.VERSION }}
path: maven

- name: Checksums
run: |
cd release
Expand All @@ -227,7 +255,7 @@ jobs:
- name: Attest build provenance
uses: actions/attest-build-provenance@v4
with:
subject-path: 'release/*.aar, release/*.apk'
subject-path: 'release/*.aar, release/*.apk, maven/**/*.aar, maven/**/*.jar, maven/**/*.pom'

- name: Tag release
id: tag
Expand Down Expand Up @@ -267,3 +295,91 @@ jobs:
-f state="$STATE" \
-f description="$DESCRIPTION" \
-f context="release"

publish-github:
name: Publish to GitHub Packages
runs-on: ubuntu-latest
needs: [version, release]
if: needs.version.outputs.tag_exists != 'true'
permissions:
packages: write
env:
VERSION: ${{ needs.version.outputs.version }}

steps:
- name: Download Maven artifacts
uses: actions/download-artifact@v8
with:
name: maven-${{ env.VERSION }}
path: maven

# Same files attested in the release job, uploaded as Gradle does:
# artifacts first, maven-metadata.xml last.
- name: Upload to GitHub Packages
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd maven
{ find . -type f ! -name 'maven-metadata.xml*' | sort; find . -type f -name 'maven-metadata.xml*' | sort; } > "$RUNNER_TEMP/files"
while read -r FILE; do
echo "Uploading ${FILE#./}"
curl --fail-with-body -sS -u "${{ github.actor }}:$GH_TOKEN" --upload-file "$FILE" \
"https://maven.pkg.github.com/${{ github.repository }}/${FILE#./}"
done < "$RUNNER_TEMP/files"

publish-central:
name: Publish to Maven Central
runs-on: ubuntu-latest
needs: [version, release]
if: needs.version.outputs.tag_exists != 'true'
env:
VERSION: ${{ needs.version.outputs.version }}
CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}

steps:
- name: Download Maven artifacts
uses: actions/download-artifact@v8
with:
name: maven-${{ env.VERSION }}
path: maven

# Central Portal API: https://central.sonatype.org/publish/publish-portal-api/
- name: Upload to Maven Central
run: |
if [ -z "$CENTRAL_USERNAME" ] || [ -z "$CENTRAL_PASSWORD" ]; then
echo "::warning::MAVEN_CENTRAL_USERNAME and MAVEN_CENTRAL_PASSWORD not configured - skip Maven Central"
exit 0
fi
if ! find maven -name '*.asc' | grep -q .; then
echo "::error::Maven artifacts are not signed - configure SIGNING_KEY and SIGNING_PASSWORD"
exit 1
fi

# Maven Central manages maven-metadata.xml itself
(cd maven && zip -qr "$RUNNER_TEMP/bundle.zip" . -x '*maven-metadata.xml*')
AUTH="Authorization: Bearer $(printf '%s:%s' "$CENTRAL_USERNAME" "$CENTRAL_PASSWORD" | base64 -w0)"
DEPLOYMENT=$(curl --fail-with-body -sS -H "$AUTH" -F "bundle=@$RUNNER_TEMP/bundle.zip" \
"https://central.sonatype.com/api/v1/publisher/upload?name=${{ github.event.repository.name }}-$VERSION&publishingType=AUTOMATIC")
echo "Deployment $DEPLOYMENT"

# Wait for the validation, the publication itself can take a while longer
for _ in $(seq 60); do
STATUS=$(curl --fail-with-body -sS -X POST -H "$AUTH" "https://central.sonatype.com/api/v1/publisher/status?id=$DEPLOYMENT")
STATE=$(echo "$STATUS" | jq -r .deploymentState)
echo "State: $STATE"
case "$STATE" in
PUBLISHING|PUBLISHED)
echo "### Maven Central: \`$STATE\`" >> "$GITHUB_STEP_SUMMARY"
exit 0
;;
FAILED)
echo "$STATUS" | jq .
echo "::error::Maven Central rejected the deployment $DEPLOYMENT"
exit 1
;;
esac
sleep 20
done
echo "::error::Maven Central did not validate the deployment $DEPLOYMENT in time"
exit 1
25 changes: 9 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# FlowLayoutManager

[![CI](https://github.com/simonebortolin/FlowLayoutManager/actions/workflows/ci.yml/badge.svg)](https://github.com/simonebortolin/FlowLayoutManager/actions/workflows/ci.yml)
[![Maven Central](https://img.shields.io/maven-central/v/io.github.simonebortolin/FlowLayoutManager)](https://central.sonatype.com/artifact/io.github.simonebortolin/FlowLayoutManager)
[![](https://jitpack.io/v/simonebortolin/FlowLayoutManager.svg)](https://jitpack.io/#simonebortolin/FlowLayoutManager)
[![API](https://img.shields.io/badge/API-21%2B-brightgreen.svg)](https://developer.android.com/about/versions/lollipop)

Expand All @@ -15,28 +16,20 @@ FlowLayoutManager is a layoutManager that works with Android ___RecyclerView___

## Installation


Add remote maven url (in `settings.gradle`)
The library is published on Maven Central, add the dependency (remember to check for latest release)

```groovy
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
}
dependencies {
implementation 'io.github.simonebortolin:FlowLayoutManager:1.10.0'
}
```

Every release also ships the `.aar` and the sample app `.apk` on the [Releases page](https://github.com/simonebortolin/FlowLayoutManager/releases).
It is also available on [JitPack](https://jitpack.io/#simonebortolin/FlowLayoutManager) as `com.github.simonebortolin:FlowLayoutManager`
(add `maven { url "https://jitpack.io" }` to the repositories in `settings.gradle`) and on
[GitHub Packages](https://github.com/simonebortolin/FlowLayoutManager/packages), which requires a GitHub token to download.

Now add a library dependency (remember to check for latest release)

```groovy
dependencies {
implementation 'com.github.simonebortolin:FlowLayoutManager:1.9.0'
}
```
Every release also ships the `.aar` and the sample app `.apk`, with their build provenance attestation,
on the [Releases page](https://github.com/simonebortolin/FlowLayoutManager/releases).

Item per line limitation
---
Expand Down
48 changes: 47 additions & 1 deletion flowlayoutmanager/build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
plugins {
alias(libs.plugins.android.library)
id 'maven-publish'
id 'signing'
}

group = 'com.github.simonebortolin'
// Maven Central and GitHub Packages serve the library as io.github.simonebortolin,
// JitPack (which sets JITPACK) as com.github.simonebortolin.
group = System.getenv('JITPACK') ? 'com.github.simonebortolin' : 'io.github.simonebortolin'
version = VERSION_NAME

android {
Expand Down Expand Up @@ -33,6 +36,8 @@ android {
publishing {
singleVariant('release') {
withSourcesJar()
// Required by Maven Central
withJavadocJar()
}
}
}
Expand All @@ -52,7 +57,48 @@ afterEvaluate {
release(MavenPublication) {
from components.release
artifactId = 'FlowLayoutManager'

// Metadata required by Maven Central
pom {
name = 'FlowLayoutManager'
description = 'A RecyclerView LayoutManager that lays out views in flow style.'
url = 'https://github.com/simonebortolin/FlowLayoutManager'
licenses {
license {
name = 'GNU General Public License v3.0'
url = 'https://www.gnu.org/licenses/gpl-3.0.txt'
}
}
developers {
developer {
id = 'simonebortolin'
name = 'Simone Bortolin'
url = 'https://github.com/simonebortolin'
}
}
scm {
url = 'https://github.com/simonebortolin/FlowLayoutManager'
connection = 'scm:git:https://github.com/simonebortolin/FlowLayoutManager.git'
developerConnection = 'scm:git:ssh://git@github.com/simonebortolin/FlowLayoutManager.git'
}
}
}
}
repositories {
// Maven layout that CI uploads to GitHub Packages and Maven Central
maven {
name = 'staging'
url = layout.buildDirectory.dir('staging-deploy')
}
}
}

// Signed only when CI provides the key (ORG_GRADLE_PROJECT_signingKey and signingPassword)
def signingKey = findProperty('signingKey')
if (signingKey) {
signing {
useInMemoryPgpKeys(signingKey, findProperty('signingPassword'))
sign publishing.publications.release
}
}
}
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Version of the library and of the sample app, used by CI to tag and release.
VERSION_NAME=1.9.0
VERSION_CODE=19
VERSION_NAME=1.10.0
VERSION_CODE=20
# Keep it as low as the dependencies allow, library and sample app share it.
MIN_SDK=21

Expand Down
Loading