Skip to content

Commit

Permalink
chore: Added CI
Browse files Browse the repository at this point in the history
Added workflows for:
- Creating releases
- Running checks
- Publishing the app
- Translating resources
- Performing health checks
- Updating the Gradle wrapper

Also added a Dependabot configuration file and a release-please configuration file.
  • Loading branch information
diareuse committed Dec 18, 2024
1 parent 2220dbf commit 8539a63
Show file tree
Hide file tree
Showing 14 changed files with 315 additions and 33 deletions.
25 changes: 25 additions & 0 deletions .github/actions/android/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Android Action
description: Prepares Android runtime (ie. installs java and sets everything up)

runs:
using: composite
steps:
- name: Set Java
uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin

- name: Enable cache
uses: actions/cache@v4
id: cache-android
with:
path: |
~/.android
key: ${{ runner.os }}-android

- name: Setup Android
uses: android-actions/setup-android@v3

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
14 changes: 14 additions & 0 deletions .github/actions/translate/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM python:3.11-slim AS builder
ADD . /app
WORKDIR /app

# We are installing a dependency here directly into our app source dir
RUN pip install --target=/app -r requirements.txt

# A distroless container image with Python and some basics like SSL certificates
# https://github.com/GoogleContainerTools/distroless
FROM gcr.io/distroless/python3-debian12
COPY --from=builder /app /app
WORKDIR /app
ENV PYTHONPATH /app
CMD ["/app/main.py"]
12 changes: 12 additions & 0 deletions .github/actions/translate/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Translate Android Resources
description: Uses Gemini LLM to use default english resources and translates them to all languages
inputs:
geminiApiKey:
required: true
filePath:
required: true
description: "Path to the originating file without any affix. Preferably this would be an English file"

runs:
using: "docker"
image: "Dockerfile"
95 changes: 95 additions & 0 deletions .github/actions/translate/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import os
import pathlib
import re
from time import sleep

import google.generativeai as genai

# === STATIC ===
QUOTA = 10 # per minute


# === STATIC ===

def set_github_action_output(output_name, output_value):
f = open(os.path.abspath(os.environ["GITHUB_OUTPUT"]), "a")
f.write(f'{output_name}={output_value}')
f.close()


def translate(lang: str, path: str, model):
segments = path.split("/")
resdir = segments[:-2]
values = segments[-2:]
resdir.append(f"{values[0]}-{lang}")
resdir.append(values[1])
output = "/".join(resdir)
print(f"Preparing output file:\n{output}")
pathlib.Path(output).parent.mkdir(parents=True, exist_ok=True)

with open(path) as f:
content = f.read()

intro = f"""Use the following xml code block for android resources as a source for translation. I will request translating the source to various languages, I need output of a xml code block with the same keys as in the original in the specified languages without any explanation or any other such thing. You will need to prefix character `'` with a single `\\` if it is not prefixed already or replace `'` with `'`. Ensure that the first `xml` tag definition is identical to the source, including version and encoding. Optionally use a "context" attribute of a string resource to properly translate the resource to the desired language. Use the "context" property as a context where the translation is not straightforward and use it to find similar expression in the desired languages. Do not translate "context" property and do include the property in translated strings.
```
{content}
```
"""

print(f"Generating output… ", end="")
response = model.generate_content(f"{intro}\ntranslate to '{lang}'")
pattern = r"^```(?:\w+)?\s*\n(.*?)(?=^```)```"
block: str = re.findall(pattern, response.text, re.DOTALL | re.MULTILINE)[0]

with open(output, "w") as f:
f.write(block.replace("'", "\\'"))

print("DONE")


def find_strings_xml(directory):
matching_files = []

for root, dirs, files in os.walk(directory):
for file in files:
if file == "strings.xml":
file_path = os.path.join(root, file)
if file_path.endswith("values/strings.xml"):
matching_files.append(file_path)

return matching_files


def main():
print("Configuring Gemini… ", end="")
genai.configure(api_key=os.environ["INPUT_GEMINIAPIKEY"])
model = genai.GenerativeModel("gemini-1.5-flash")
print("DONE")

languages = ["af", "am", "ar", "as", "az", "be", "bg", "bn", "bs", "ca", "cs", "da", "de", "el", "es", "et", "eu",
"fa",
"fi", "fil", "fr", "gl", "gu", "hi", "hr", "hu", "hy", "in", "is", "it", "iw", "ja", "ka", "kk", "km",
"kn", "ko", "ky", "lo", "lt", "lv", "mk", "ml", "mn", "mr", "ms", "my", "nb", "ne", "nl", "or", "pa",
"pl",
"pt", "ro", "ru", "si", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th", "tr", "uk", "ur", "uz",
"vi",
"zh", "zu"]

root_path = os.environ["INPUT_PATH"]
result = find_strings_xml(root_path if root_path else ".")

print(f"Found {len(result)} files named 'strings.xml':")
for path in result:
print(path)

print(f"""Translation will be performed for {len(languages)} languages.
This process will take approximately {len(languages) / QUOTA} minutes""")

for l in languages:
translate(l, path, model)
sleep(1 / QUOTA)


if __name__ == "__main__":
main()
28 changes: 28 additions & 0 deletions .github/actions/translate/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
annotated-types==0.7.0
cachetools==5.5.0
certifi==2024.12.14
charset-normalizer==3.4.0
google-ai-generativelanguage==0.6.10
google-api-core==2.24.0
google-api-python-client==2.155.0
google-auth==2.37.0
google-auth-httplib2==0.2.0
google-generativeai==0.8.3
googleapis-common-protos==1.66.0
grpcio==1.68.1
grpcio-status==1.68.1
httplib2==0.22.0
idna==3.10
proto-plus==1.25.0
protobuf==5.29.1
pyasn1==0.6.1
pyasn1_modules==0.4.1
pydantic==2.10.3
pydantic_core==2.27.1
pyparsing==3.2.0
requests==2.32.3
rsa==4.9
tqdm==4.67.1
typing_extensions==4.12.2
uritemplate==4.1.1
urllib3==2.2.3
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ updates:
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore"
include: "scope"
reviewers:
- "diareuse"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore"
include: "scope"
reviewers:
- "diareuse"
43 changes: 18 additions & 25 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,34 @@ on:
jobs:
test:
runs-on: ubuntu-latest

permissions:
checks: write
pull-requests: write

steps:
- uses: actions/checkout@v4

- run: |
chmod +x setup.sh
./setup.sh
- name: Set Java
uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin

- name: Setup Android SDK
uses: android-actions/setup-android@v3

- name: Build with Gradle
uses: gradle/gradle-build-action@v3
- uses: diareuse/movie-metropolis/.github/actions/android@master
- uses: gradle/gradle-build-action@v3
with:
arguments: test

- name: Publish Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
arguments: check
- uses: dorny/test-reporter@v1
if: always()
with:
junit_files: "**/test-results/**/*.xml"
name: Tests
path: "**/test-results/**/*.xml"
reporter: java-junit
fail-on-empty: false
builds:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: diareuse/movie-metropolis/.github/actions/android@master
- uses: gradle/gradle-build-action@v3
with:
arguments: assemble

dependabot:
merge:
runs-on: ubuntu-latest
needs: [ test ]
needs: [ check, builds ]
permissions:
pull-requests: write
issues: write
Expand Down
23 changes: 23 additions & 0 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Create Release
on:
push:
branches:
- master

permissions:
contents: write
pull-requests: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ github.token }}
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
26 changes: 26 additions & 0 deletions .github/workflows/healthcheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Health Check

on:
workflow_dispatch:
push:
branches:
- master

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
perform-health-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: diareuse/movie-metropolis/.github/actions/android@master
- uses: gradle/actions/dependency-submission@v4
with:
dependency-graph-exclude-projects: ':buildSrc', 'movie-metropolis'
dependency-graph-exclude-configurations: '.*[Tt]est(Compile|Runtime)Classpath'
dependency-resolution-task: assemble
build-scan-publish: true
build-scan-terms-of-use-url: "https://gradle.com/help/legal-terms-of-use"
build-scan-terms-of-use-agree: "yes"
27 changes: 27 additions & 0 deletions .github/workflows/i18n.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: i18n

on:
workflow_dispatch:
push:
branches:
- master
paths:
- '**/values/strings.xml'

permissions:
contents: write
pull-requests: write

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: diareuse/movie-metropolis/.github/actions/translate@master
secrets: inherit
with:
filePath: "app/src/main/res/values/strings.xml"
9 changes: 1 addition & 8 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,7 @@ jobs:
versionNumber=$(($versionNumber / 10 + 1))
sed -i "s/versionCode 1/versionCode $versionNumber/" buildSrc/src/main/groovy/movie.metropolis.app.gradle
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Android SDK
uses: android-actions/setup-android@v3
- uses: diareuse/movie-metropolis/.github/actions/android@master

- name: Build with Gradle
uses: gradle/gradle-build-action@v3
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/update-gradle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Update Gradle Wrapper

on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
update-gradle-wrapper:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: diareuse/movie-metropolis/.github/actions/android@master

- name: Update Gradle Wrapper
uses: gradle-update/update-gradle-wrapper-action@v2
with:
commit-message-template: 'chore(gradle): Bump Gradle Wrapper from %sourceVersion% to %targetVersion%'
3 changes: 3 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
".": "0.0.0"
}
11 changes: 11 additions & 0 deletions release-please-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"always-update": true,
"include-v-in-tag": false,
"release-type": "simple",
"packages": {
".": {
"changelog-path": "CHANGELOG.md"
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}

0 comments on commit 8539a63

Please sign in to comment.