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
11 changes: 11 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Set up JDK and Gradle
description: The JDK and Gradle setup that every Gradle job uses. Run it after actions/checkout.

runs:
using: composite
steps:
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 17
- uses: gradle/actions/setup-gradle@v6
153 changes: 65 additions & 88 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ name: CI

on:
push:
branches:
- master
branches: [master]
pull_request:
branches:
- master

permissions:
contents: read
Expand All @@ -16,93 +13,93 @@ concurrency:
cancel-in-progress: true

jobs:
build:
name: Format, lint, and build
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 30

timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up JDK 17
uses: actions/setup-java@v5
- uses: actions/checkout@v6
- uses: ./.github/actions/setup
- run: ./gradlew spotlessCheck lint
- uses: actions/upload-artifact@v7
if: failure()
with:
distribution: temurin
java-version: 17

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6

- name: Check formatting
run: ./gradlew spotlessCheck

- name: Run Android lint
run: ./gradlew lint

- name: Build TrustKit library
run: ./gradlew :trustkit:assembleRelease

- name: Build Java demo app
run: ./gradlew :app:assembleDebug

- name: Build Kotlin demo app
run: ./gradlew :demoappkotlin:assembleDebug
name: lint-reports
path: "**/build/reports/**"
if-no-files-found: ignore
retention-days: 7

- name: Upload build reports
unit-tests:
name: Unit tests
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup
- run: ./gradlew :trustkit:testDebugUnitTest
- uses: actions/upload-artifact@v7
if: failure()
uses: actions/upload-artifact@v7
with:
name: build-reports
path: |
**/build/reports/**
**/build/outputs/logs/**
name: unit-test-reports
path: trustkit/build/reports/tests/**
if-no-files-found: ignore
retention-days: 7

script-tests:
name: Script tests
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- run: ./scripts/test_publish_maven_central.sh

release-bundle:
name: Build release bundle
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup
- run: ./scripts/build_release_bundle.sh

demo:
name: Build demo ${{ matrix.module }}
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
module: [app, demoappkotlin]
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup
- run: ./gradlew :${{ matrix.module }}:assembleDebug

instrumentation-tests:
name: Instrumentation tests (API ${{ matrix.api-level }})
needs: build
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
api-level:
- 27
- 36

api-level: [27, 36]
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 17

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6

- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
| sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- name: Run instrumentation tests
uses: reactivecircus/android-emulator-runner@v2.37.0
- uses: actions/checkout@v6
- uses: ./.github/actions/setup
- run: ./scripts/enable_kvm.sh
- uses: reactivecircus/android-emulator-runner@v2.37.0
with:
api-level: ${{ matrix.api-level }}
arch: x86_64
target: default
script: ./gradlew :trustkit:connectedDebugAndroidTest

- name: Upload instrumentation test reports
- uses: actions/upload-artifact@v7
if: failure()
uses: actions/upload-artifact@v7
with:
name: instrumentation-reports-api-${{ matrix.api-level }}
path: |
Expand All @@ -111,23 +108,3 @@ jobs:
trustkit/build/outputs/managed_device_android_test_additional_output/**
if-no-files-found: ignore
retention-days: 7
Comment thread
alexanderdibenedetto marked this conversation as resolved.
Resolved

ci-checks:
name: CI checks
runs-on: ubuntu-latest
if: ${{ always() }}
needs:
- build
- instrumentation-tests
steps:
- name: Verify required jobs succeeded
env:
BUILD_RESULT: ${{ needs.build.result }}
INSTRUMENTATION_TESTS_RESULT: ${{ needs.instrumentation-tests.result }}
run: |
if [[ "$BUILD_RESULT" != "success" || "$INSTRUMENTATION_TESTS_RESULT" != "success" ]]; then
echo "Build result: $BUILD_RESULT"
echo "Instrumentation tests result: $INSTRUMENTATION_TESTS_RESULT"
exit 1
fi
echo "All necessary CI jobs completed successfully"
50 changes: 50 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Release

on:
release:
types: [published]

permissions:
contents: read

# github.ref_name can be empty on release events.
env:
TAG: ${{ github.event.release.tag_name }}

# One group per tag: a shared group cancels pending runs, which would skip a release.
concurrency:
group: maven-central-release-${{ github.event.release.tag_name }}
cancel-in-progress: false
Comment thread
alexanderdibenedetto marked this conversation as resolved.
Resolved

jobs:
verify:
name: Verify release version
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6
- run: ./scripts/verify_release_version.sh "$TAG"

publish:
name: Publish release bundle
needs: verify
runs-on: ubuntu-latest
timeout-minutes: 60
environment: maven-central
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/setup
- run: ./scripts/build_release_bundle.sh
env:
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
SIGNING_KEY_PASSWORD: ${{ secrets.SIGNING_KEY_PASSWORD }}
# Attach first: this step can be re-run, but the Maven Central upload cannot.
- run: gh release upload "$TAG" output/trustkit-*.zip --clobber
env:
GH_TOKEN: ${{ github.token }}
- run: ./scripts/publish_maven_central.sh
env:
MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*.iml
local.properties
*/debug/*
/output/
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ TrustKit Android

[![CI](https://github.com/datatheorem/TrustKit-Android/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/datatheorem/TrustKit-Android/actions/workflows/ci.yml?query=branch%3Amaster)
[![API](https://img.shields.io/badge/API-16%2B-blue.svg?style=flat)](https://android-arsenal.com/api?level=16)
[![Version](https://img.shields.io/bintray/v/datatheoremoss/TrustKit-Android/trustkit.svg)](https://bintray.com/datatheoremoss/TrustKit-Android/trustkit)
[![Maven Central](https://img.shields.io/maven-central/v/com.datatheorem.android.trustkit/trustkit.svg)](https://central.sonatype.com/artifact/com.datatheorem.android.trustkit/trustkit)
[![MIT License](https://img.shields.io/github/license/datatheorem/trustkit-android.svg)](https://en.wikipedia.org/wiki/MIT_License)
[![Gitter chat](https://badges.gitter.im/datatheorem/gitter.png)](https://gitter.im/TrustKit/Lobby)

Expand Down Expand Up @@ -42,6 +42,10 @@ Add TrustKit to your project's _build.gradle_:

`implementation 'com.datatheorem.android.trustkit:trustkit:<last_version>'`

To receive pinning failure reports with a local broadcast receiver, also add:

`implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'`

### Configuring a Pinning Policy

Deploying SSL pinning in the App requires initializing TrustKit with a pinning policy (domains, pins, and additional settings). The policy is wrapped in the official [Android N Network Security Configuration](https://developer.android.com/training/articles/security-config.html) i.e :
Expand Down Expand Up @@ -205,6 +209,21 @@ On Android M and earlier devices, TrustKit provides uses its own implementation

For consumers of TrustKit's OkHttpHelper solutions, redirects must to be disabled as Pinning will currently only work properly on the initial request and not any redirects

Releasing
---------

1. Set `trustkitVersionName` (and increment `trustkitVersionCode`) in `gradle/libs.versions.toml` and merge to `master`.
2. Publish a GitHub release whose tag equals that version, for example `1.2.0`. Every published release, including pre-releases, goes to Maven Central.

The `Release` workflow then attaches `trustkit-<version>.zip` to the GitHub release and publishes the same zip to Maven Central. It does not run CI again: release a commit that already passed CI on `master`. A Maven Central release cannot be removed, so check the version before you publish.

The zip is a Maven repository: the AAR, POM, Gradle module metadata, sources and javadoc, each with checksums and a signature. To use it without Maven Central, unzip it and add the folder as a `maven { url }` repository. `scripts/build_release_bundle.sh` builds it locally (unsigned unless `SIGNING_KEY` is set).

The workflow reads these secrets from the `maven-central` GitHub environment:

* `MAVEN_CENTRAL_USERNAME`, `MAVEN_CENTRAL_PASSWORD`: a Central Portal user token.
* `SIGNING_KEY`, `SIGNING_KEY_PASSWORD`: the ASCII-armored PGP private key and its passphrase.

License
-------

Expand Down
Loading
Loading