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

Docker, Dependabot and GitHub Workflows #1198

Merged
merged 11 commits into from
Dec 10, 2024
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
45 changes: 45 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: 2
updates:
- package-ecosystem: gradle
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
groups:
dagger:
patterns:
- "com.google.dagger:dagger*"
ignore:
- dependency-name: androidx.annotation:annotation
versions:
- "> 1.1.0"
- dependency-name: androidx.constraintlayout:constraintlayout
versions:
- "> 1.1.3"
- dependency-name: com.android.tools.build:gradle
versions:
- "> 3.6.3"
- dependency-name: com.github.triplet.play
versions:
- "> 2.8.0"
- dependency-name: com.google.android.material:material
versions:
- "> 1.0.0"
- dependency-name: com.google.zxing:core
versions:
- "> 3.3.0"
- dependency-name: com.google.dagger:dagger-compiler
versions:
- 2.31.2
- "2.32"
- "2.33"
- "2.34"
- 2.34.1
- "2.35"
- dependency-name: com.google.dagger:dagger
versions:
- 2.31.2
- "2.32"
- "2.33"
- "2.34"
- 2.34.1
17 changes: 17 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Description
Describe what this PR is about

# Changes
What changes are made in this PR
* change 1
* change 2

# Screenshots
In case of UI changes, add before and after screenshots

| Before | After |
| ------ | ----- |
| ![before][] | ![after][] |

[before]: before.png
[after]: after.png
42 changes: 42 additions & 0 deletions .github/workflows/build-app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Build App

on:
pull_request:
push:
branches:
- main
- release

env:
# Our build metadata
BUILD_USER: android-builder
BUILD_HOST: github.syncthing.net

jobs:
build:
name: Debug Build
runs-on: ubuntu-latest
container: ghcr.io/syncthing/syncthing-android-builder
steps:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0

- name: build
run: |
git config --system --add safe.directory '*'
java -version
./gradlew --no-daemon buildNative lint assembleDebug

- uses: actions/upload-artifact@v3
with:
name: syncthing-android-debug.apk
path: app/build/outputs/apk/debug/app-debug.apk

- uses: actions/upload-artifact@v3
with:
name: reports-and-libs
path: |
app/build/reports/**
app/src/main/jniLibs/**
20 changes: 20 additions & 0 deletions .github/workflows/build-builder.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Builder Image

on:
pull_request:
paths:
- 'docker/**'
workflow_dispatch:

jobs:
build-image:
if: github.event_name == 'pull_request'
uses: ./.github/workflows/image-builder-template.yaml
with:
push: false

push-image:
if: github.event_name == 'workflow_dispatch'
uses: ./.github/workflows/image-builder-template.yaml
with:
push: true
41 changes: 41 additions & 0 deletions .github/workflows/image-builder-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Image Builder Template

on:
workflow_call:
inputs:
push:
required: true
type: boolean

env:
# Our build metadata
BUILD_USER: android-builder
BUILD_HOST: github.syncthing.net
# template var
image: ghcr.io/syncthing/syncthing-android-builder

jobs:
build-image:
name: Build Builder Docker
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0

- uses: docker/setup-buildx-action@v2

- uses: docker/login-action@v2
if: ${{ inputs.push }}
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- uses: docker/build-push-action@v4
with:
context: .
file: ./docker/Dockerfile
tags: '${{ env.image }}:latest,${{ env.image }}:${{ github.sha }}'
push: ${{ inputs.push }}
63 changes: 63 additions & 0 deletions .github/workflows/release-app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Release App

on:
push:
# Cannot filter on both branches (release) and tags - it's ORed
tags:
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+-rc\.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+-rc\.[0-9]+\.[0-9]+'

env:
# Our build metadata
BUILD_USER: android-builder
BUILD_HOST: github.syncthing.net

jobs:
release:
name: Release Build and Publish
runs-on: ubuntu-latest
container: ghcr.io/syncthing/syncthing-android-builder
steps:
- uses: actions/checkout@v3
with:
submodules: true
fetch-depth: 0

- name: Ensure release branch
run: |
git config --system --add safe.directory '*'
if ! git branch -a --contains $(git rev-parse HEAD) | grep release >/dev/null; then
echo "Tag is not part of release branch - aborting..."
exit 1
fi

- name: build_release
env:
SYNCTHING_RELEASE_KEY_ALIAS: android
SIGNING_PASSWORD: '${{ secrets.SIGNING_PASSWORD }}'
SYNCTHING_RELEASE_STORE_FILE: '${{ runner.temp }}/signing-keystore.jks'
SYNCTHING_RELEASE_PLAY_ACCOUNT_CONFIG_FILE: '${{ runner.temp }}/google-play-secrets.json'
shell: bash
run: |
set -eu -o pipefail
echo '${{ secrets.SIGNING_KEYSTORE_JKS_BASE64 }}' | base64 -d > "$SYNCTHING_RELEASE_STORE_FILE"
echo '${{ secrets.GOOGLE_PLAY_SECRETS_BASE64 }}' | base64 -d > "$SYNCTHING_RELEASE_PLAY_ACCOUNT_CONFIG_FILE"
java -version
# TODO: Readd publishReleaseBundle if google play works again, or
# remove everything related to publishing to google play.
./gradlew --no-daemon buildNative lint assembleRelease bundleRelease
rm "$SYNCTHING_RELEASE_STORE_FILE" "$SYNCTHING_RELEASE_PLAY_ACCOUNT_CONFIG_FILE"

echo '${{ secrets.GNUPG_SIGNING_KEY_BASE64 }}' | base64 -d | gpg --import
cd app/build/outputs/apk/release
sha256sum app-release.apk | gpg --clearsign > sha256sum.txt.asc

- uses: ncipollo/release-action@v1
with:
artifacts: "app/build/outputs/apk/release/*.apk,app/build/outputs/apk/release/*.asc"
artifactErrorsFailBuild: true
bodyFile: "app/src/main/play/release-notes/en-GB/default.txt"
prerelease: ${{ contains('-rc.', github.ref_name) }}
draft: true
46 changes: 31 additions & 15 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,41 +1,57 @@
FROM openjdk:8
FROM eclipse-temurin:11-jdk-jammy

ENV GO_VERSION 1.11.4
ENV ANDROID_SDK_VERSION 4333796
ENV GO_VERSION 1.22.7

# Can be found scrolling down on this page:
# https://developer.android.com/studio/index.html#command-tools
ARG ANDROID_SDK_FILENAME=commandlinetools-linux-9123335_latest.zip
WORKDIR /opt

# The '--reinstall' combined with 'build-essentials' is necessary for cgo
# compilation of go std libs to work. A terrible, arcane hack to solve arkane
# cgo issues - almost fitting.
RUN apt-get update && apt-get install --reinstall --no-install-recommends -y build-essential gcc unzip git gnupg python3

# Install Go
RUN wget -q https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz && \
RUN wget -nv https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz && \
tar -zxf go${GO_VERSION}.linux-amd64.tar.gz && \
rm go${GO_VERSION}.linux-amd64.tar.gz
ENV GOROOT /opt/go
ENV PATH /opt/go/bin:${PATH}

# Install Android SDK manager
RUN mkdir -p /opt/android-sdk && cd /opt/android-sdk && \
wget -q https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_VERSION}.zip && \
unzip -q sdk-tools-linux-${ANDROID_SDK_VERSION}.zip && \
rm sdk-tools-linux-${ANDROID_SDK_VERSION}.zip
wget -q https://dl.google.com/android/repository/${ANDROID_SDK_FILENAME} && \
unzip -q ${ANDROID_SDK_FILENAME} && \
rm ${ANDROID_SDK_FILENAME}
ENV ANDROID_HOME /opt/android-sdk

ARG SDKMANAGER="${ANDROID_HOME}/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME}"

# Accept the SDK license, as we can't install packages otherwise
RUN yes | ${ANDROID_HOME}/tools/bin/sdkmanager --licenses
RUN yes | $SDKMANAGER --licenses > /dev/null

# NDK version
ENV NDK_VERSION 27.0.12077973
ENV TARGET_SDK_VERSION 35

# Install other android packages, including NDK
RUN ${ANDROID_HOME}/tools/bin/sdkmanager tools platform-tools "build-tools;28.0.3" "platforms;android-28" "extras;android;m2repository" ndk-bundle
RUN $SDKMANAGER tools platform-tools "build-tools;${TARGET_SDK_VERSION}.0.0" "platforms;android-${TARGET_SDK_VERSION}" "extras;android;m2repository" "ndk;${NDK_VERSION}"

# Accept licenses of newly installed packages
RUN yes | ${ANDROID_HOME}/tools/bin/sdkmanager --licenses

# Setup the NDK path
ENV ANDROID_NDK_HOME ${ANDROID_HOME}/ndk-bundle
RUN yes | $SDKMANAGER --licenses

# Enable prebuild mode
ENV SYNCTHING_ANDROID_PREBUILT 1

# Set location of go cache
ENV GOCACHE /opt/gocache

# Set location of GOPATH to persist packages for module builds in GOPATH/pkg/mod
ENV GOPATH /opt/gopath

# Run prebuild script (will prebuild stuff into the image if env var is set)
ADD prebuild.sh /opt/prebuild.sh
RUN /opt/prebuild.sh
ADD . /opt/syncthing-android
RUN /opt/syncthing-android/docker/prebuild.sh

WORKDIR /mnt
18 changes: 13 additions & 5 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# How to use this

1. Build the docker image: `docker build -t syncthing-android-builder:latest .`
2. Checkout syncthing-android somewhere (for the sake of discussion let's say /tmp/syncthing-android)
3. Inside /tmp/syncthing-android, do `git submodule init; git submodule update`
4. Run `docker run --rm -v /tmp/syncthing-android:/mnt syncthing-android-builder ./gradlew buildNative assembleDebug`
5. Retrieve APKs from /tmp/syncthing-android/app/build/outputs
## Create the builder image

From inside the checked out syncthing-android repository, run:

`docker build -t syncthing-android-builder:latest -f ./docker/Dockerfile .`

## Build the app

1. From inside the checked out syncthing-android repository, run:
`git submodule init; git submodule update`
2. Actual build:
`docker run --rm -v /tmp/syncthing-android:/mnt syncthing-android-builder ./gradlew buildNative assembleDebug`
3. Retrieve APKs from ./app/build/outputs
42 changes: 7 additions & 35 deletions docker/prebuild.sh
Original file line number Diff line number Diff line change
@@ -1,41 +1,13 @@
#!/bin/bash -e

[ -z "$SYNCTHING_ANDROID_PREBUILT" ] && echo "Prebuild disabled" && exit 0
if [ -z "$SYNCTHING_ANDROID_PREBUILT" ]; then
echo "Prebuild disabled"
rm -rf syncthing-android
exit 0
fi

for ARCH in arm x86 arm64; do
GOARCH=${ARCH}
SDK=16
case ${ARCH} in
arm)
GCC="arm-linux-androideabi-clang"
;;
arm64)
SDK=21
GCC="aarch64-linux-android-clang"
;;
x86)
GOARCH=386
GCC="i686-linux-android-clang"
;;
*)
echo "Invalid architecture"
exit 1
esac

STANDALONE_NDK_DIR="${ANDROID_NDK_HOME}/standalone-ndk/android-${SDK}-${GOARCH}"
echo "Building standalone NDK - ${STANDALONE_NDK_DIR}"
${ANDROID_NDK_HOME}/build/tools/make-standalone-toolchain.sh \
--platform=android-${SDK} --arch=${ARCH} \
--install-dir=${STANDALONE_NDK_DIR}

echo "Pre-building Go standard library for $GOARCH"
CGO_ENABLED=1 CC="${STANDALONE_NDK_DIR}/bin/${GCC}" \
GOOS=android GOARCH=$GOARCH go install -v std
done

echo "Prepopulating gradle cache"
git clone https://github.com/syncthing/syncthing-android
echo "Prepopulating gradle and go build/pkg cache"
cd syncthing-android
./gradlew --no-daemon lint
./gradlew --no-daemon lint buildNative
cd ..
rm -rf syncthing-android