Automate Crowdin localisation sync (#1265)
* build: add a Gradle plugin for Crowdin Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> * build/crowdin: add skipCleanup extension property Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> * build/crowdin: also handle nonFree source set Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> * build/crowdin: fixup directory names for nonFree variant Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> * app: sync translations from Crowdin Signed-off-by: Harsh Shandilya <me@msfjarvis.dev> * github: add Crowdin sync workflow Signed-off-by: Harsh Shandilya <me@msfjarvis.dev>
This commit is contained in:
parent
c15594b045
commit
1a774eae23
14 changed files with 228 additions and 14 deletions
31
.github/workflows/weekly_crowdin_sync.yml
vendored
Normal file
31
.github/workflows/weekly_crowdin_sync.yml
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
name: Sync localisations from Crowdin
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * 6'
|
||||
|
||||
jobs:
|
||||
update-publicsuffix-data:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
|
||||
|
||||
- name: Download new translations from Crowdin
|
||||
run: ./gradlew crowdin
|
||||
|
||||
- name: Compare list changes
|
||||
run: if [[ $(git diff --stat) != '' ]]; then echo "UPDATED=true" >> $GITHUB_ENV; fi
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@c7f493a8000b8aeb17a1332e326ba76b57cb83eb
|
||||
if: env.UPDATED == 'true'
|
||||
with:
|
||||
assignees: msfjarvis
|
||||
author: GitHub Actions <noreply@github.com>
|
||||
base: develop
|
||||
body: This is an automated pull request to sync localisations from Crowdin.
|
||||
branch: bot/crowdin-sync
|
||||
commit-message: "strings: sync with crowdin"
|
||||
labels: A-localisation, P-low, S-waiting-on-review
|
||||
title: Sync localisations from Crowdin
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -8,6 +8,11 @@ plugins {
|
|||
id("com.android.application")
|
||||
kotlin("android")
|
||||
`aps-plugin`
|
||||
`crowdin-plugin`
|
||||
}
|
||||
|
||||
configure<CrowdinExtension> {
|
||||
projectName = "android-password-store"
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
@ -84,10 +84,10 @@
|
|||
<string name="crypto_save_and_copy">Gardar e copiar</string>
|
||||
<!-- DECRYPT Layout -->
|
||||
<string name="action_search">Buscar</string>
|
||||
<string name="password">Contrasinal:</string>
|
||||
<string name="otp">OTP:</string>
|
||||
<string name="password">Contrasinal</string>
|
||||
<string name="otp">OTP</string>
|
||||
<string name="extra_content">Contido extra:</string>
|
||||
<string name="username">Nome de usuaria:</string>
|
||||
<string name="username">Nome de usuaria</string>
|
||||
<string name="edit_password">Editar contrasinal</string>
|
||||
<string name="copy_password">Copiar contrasinal</string>
|
||||
<string name="share_as_plaintext">Compartir como texto plano</string>
|
||||
|
@ -200,16 +200,17 @@
|
|||
<string name="send_plaintext_password_to">Enviar contrasinal como texto plano usando...</string>
|
||||
<string name="app_icon_hint">Icona da app</string>
|
||||
<!-- Oreo Autofill -->
|
||||
<string name="oreo_autofill_select_and_fill_into">Elixe o elemento a completar</string>
|
||||
<string name="oreo_autofill_strict_domain_search">Busca resistente ó phishing</string>
|
||||
<string name="oreo_autofill_match_with">Coincidencia con %1$s</string>
|
||||
<string name="oreo_autofill_matches_clear_existing">Baleirar coincidencias existentes</string>
|
||||
<string name="oreo_autofill_filter_no_results">Sen resultados.</string>
|
||||
<string name="oreo_autofill_search_in_store">Buscar no almacenaxe...</string>
|
||||
<string name="oreo_autofill_search_in_store">Buscar elemento</string>
|
||||
<string name="oreo_autofill_save_internal_error">Non se puido gardar por un fallo interno</string>
|
||||
<string name="oreo_autofill_save_app_not_supported">Esta app non está soportada actualmente</string>
|
||||
<string name="oreo_autofill_save_passwords_dont_match">Non concordan os contrasinais</string>
|
||||
<string name="oreo_autofill_generate_password">Crear contrasinal...</string>
|
||||
<string name="oreo_autofill_fill_otp_from_sms">Extraer código do SMS…</string>
|
||||
<string name="oreo_autofill_generate_password">Crear elemento</string>
|
||||
<string name="oreo_autofill_fill_otp_from_sms">Extraer código do SMS</string>
|
||||
<string name="oreo_autofill_max_matches_reached">Acadouse o máximo número de coincidencias (%1$d); eliminar as coincidencias antes de engadir máis.</string>
|
||||
<string name="oreo_autofill_warning_publisher_header">A autoría desta app cambiou desde que rexistraches a entrada Password Store con ela:</string>
|
||||
<string name="oreo_autofill_warning_publisher_footer"><b>A aplicación actualmente instalada podería intentar roubar as túas credenciais pretendendo ser unha app de confianza.</b>\n\nIntenta desinstalar e reinstalar
|
||||
|
@ -219,7 +220,7 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
|
|||
<string name="oreo_autofill_warning_publisher_changed_disable_autofill_button">Manter desactivado o autocompletado</string>
|
||||
<string name="oreo_autofill_warning_publisher_reenable_button">Reactivar autocompletado</string>
|
||||
<string name="oreo_autofill_warning_publisher_warning_sign_description">Aviso</string>
|
||||
<string name="oreo_autofill_warning_publisher_dataset_summary">Toca para detalles...</string>
|
||||
<string name="oreo_autofill_warning_publisher_dataset_summary">Toca para ver detalles</string>
|
||||
<string name="oreo_autofill_warning_publisher_dataset_title">Posible intento de phishing</string>
|
||||
<string name="oreo_autofill_general_fill_and_save_support">Completar e gardar credenciais</string>
|
||||
<string name="oreo_autofill_general_fill_support">Completar credenciais</string>
|
||||
|
@ -342,7 +343,20 @@ a app desde unha fonte de confianza, como a Play Store, Amazon Appstore, F-Droid
|
|||
<string name="select_repo_type_text">Escolle se queres crear un repositorio local ou clonar un remoto.</string>
|
||||
<string name="clone_remote_repo">Clonar repositorio remoto</string>
|
||||
<string name="create_local_repo">Crear repositorio local</string>
|
||||
<string name="select_gpg_key_title">Elixe\nChave\nGPG</string>
|
||||
<string name="select_gpg_key_message">Elixe a chave GPG coa que queres iniciar a almacenaxe</string>
|
||||
<string name="gpg_key_select">Elixe chave</string>
|
||||
<!-- SSH port validation -->
|
||||
<string name="ssh_scheme_needed_title">URL potencialmente incorrecto</string>
|
||||
<string name="ssh_scheme_needed_message">Semella que o teu URL contén un porto personalizado, pero non indica o esquema ssh://.\nEsto pode facer que o porto sexa considerado parte do enderezo. Preme aquí en OK para arranxalo URL.</string>
|
||||
<string name="https_scheme_with_port_title">URL HTTPS con porto personalizado</string>
|
||||
<string name="https_scheme_with_port_message">Semella que estar a usar un URL HTTPS cun porto personalizado. Esta función non está soportada, e causará problemas futuros. Preme OK para eliminar o porto do URL.</string>
|
||||
<!-- Proxy configuration activity -->
|
||||
<string name="proxy_hostname">Servidor proxy</string>
|
||||
<string name="port">Porto</string>
|
||||
<string name="pref_proxy_settings">Axustes do proxy HTTP(S)</string>
|
||||
<string name="invalid_proxy_url">URL non válido</string>
|
||||
<string name="oreo_autofill_password_fill_and_conditional_save_support">Completa e garda contrasinais (gardar require que os servizos de accesibilidade non estén activados)</string>
|
||||
<string name="clear_saved_host_key">Eliminar chave do host gardada</string>
|
||||
<string name="clear_saved_host_key_success">Eliminouse correctamente a chave gardada do host!</string>
|
||||
</resources>
|
||||
|
|
|
@ -84,10 +84,10 @@
|
|||
<string name="crypto_save_and_copy">Salva e Copia</string>
|
||||
<!-- DECRYPT Layout -->
|
||||
<string name="action_search">Cerca</string>
|
||||
<string name="password">Password:</string>
|
||||
<string name="otp">OTP:</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="otp">OTP</string>
|
||||
<string name="extra_content">Contenuto extra:</string>
|
||||
<string name="username">Nome Utente:</string>
|
||||
<string name="username">Nome Utente</string>
|
||||
<string name="edit_password">Modifica password</string>
|
||||
<string name="copy_password">Copia password</string>
|
||||
<string name="share_as_plaintext">Condividi come testo semplice</string>
|
||||
|
@ -200,16 +200,17 @@
|
|||
<string name="send_plaintext_password_to">Invia password come testo semplice usando…</string>
|
||||
<string name="app_icon_hint">Icona app</string>
|
||||
<!-- Oreo Autofill -->
|
||||
<string name="oreo_autofill_select_and_fill_into">Seleziona la voce da compilare</string>
|
||||
<string name="oreo_autofill_strict_domain_search">Ricerca resistente al phishing</string>
|
||||
<string name="oreo_autofill_match_with">Abbina con %1$s</string>
|
||||
<string name="oreo_autofill_matches_clear_existing">Cancella abbinamenti esistenti</string>
|
||||
<string name="oreo_autofill_filter_no_results">Nessun risultato.</string>
|
||||
<string name="oreo_autofill_search_in_store">Cerca nell\'archiviazione…</string>
|
||||
<string name="oreo_autofill_search_in_store">Cerca la voce</string>
|
||||
<string name="oreo_autofill_save_internal_error">Salvataggio fallito a causa di un errore interno</string>
|
||||
<string name="oreo_autofill_save_app_not_supported">Quest\'app non è attualmente supportata</string>
|
||||
<string name="oreo_autofill_save_passwords_dont_match">Le password non corrispondono</string>
|
||||
<string name="oreo_autofill_generate_password">Genera password…</string>
|
||||
<string name="oreo_autofill_fill_otp_from_sms">Estrai codice da SMS…</string>
|
||||
<string name="oreo_autofill_generate_password">Crea voce</string>
|
||||
<string name="oreo_autofill_fill_otp_from_sms">Estrai codice da SMS</string>
|
||||
<string name="oreo_autofill_max_matches_reached">Numero massimo di abbinamenti (%1$d) raggiunto; cancella le corrispondenze prima di aggiungerne di nuove.</string>
|
||||
<string name="oreo_autofill_warning_publisher_header">L\'editore di quest\'app è cambiato da quando hai associato per la prima volta una voce di Password Store con essa:</string>
|
||||
<string name="oreo_autofill_warning_publisher_footer"><b>L\'app correntemente installata potrebbe provare a rubare le tue credenziali pretendendo di essere un\'app affidabile.</b>\n\nProva a disinstallare e reinstallare l\'app da una fonte affidabile, come Play Store, Amazon, Appstore, F-Droid, o il negozio del produttore del tuo telefono.</string>
|
||||
|
@ -218,7 +219,7 @@
|
|||
<string name="oreo_autofill_warning_publisher_changed_disable_autofill_button">Mantieni l\'Auto-Completamento disabilitato</string>
|
||||
<string name="oreo_autofill_warning_publisher_reenable_button">Riabilita l\'Auto-Completamento</string>
|
||||
<string name="oreo_autofill_warning_publisher_warning_sign_description">Avviso</string>
|
||||
<string name="oreo_autofill_warning_publisher_dataset_summary">Tocca per i dettagli…</string>
|
||||
<string name="oreo_autofill_warning_publisher_dataset_summary">Tocca per i dettagli</string>
|
||||
<string name="oreo_autofill_warning_publisher_dataset_title">Possibile tentativo di phishing</string>
|
||||
<string name="oreo_autofill_general_fill_and_save_support">Compila e salva le credenziali</string>
|
||||
<string name="oreo_autofill_general_fill_support">Compila le credenziali</string>
|
||||
|
@ -341,7 +342,20 @@
|
|||
<string name="select_repo_type_text">Seleziona se vuoi creare una repo locale o clonarne una remota.</string>
|
||||
<string name="clone_remote_repo">Clona Repo Remota</string>
|
||||
<string name="create_local_repo">Crea Repo Locale</string>
|
||||
<string name="select_gpg_key_title">Seleziona\nChiave\nGPG</string>
|
||||
<string name="select_gpg_key_message">Seleziona una chiave GPG con cui inizializzare il tuo archivio</string>
|
||||
<string name="gpg_key_select">Seleziona chiave</string>
|
||||
<!-- SSH port validation -->
|
||||
<string name="ssh_scheme_needed_title">URL potenzialmente errato</string>
|
||||
<string name="ssh_scheme_needed_message">Sembra che il tuo URL contenga una porta personalizzata, ma non specifichi lo schema ssh://.\nQuesto può causare che la porta sia considerata una parte del tuo percorso. Premi OK qui per correggere l\'URL.</string>
|
||||
<string name="https_scheme_with_port_title">URL HTTPS con porta personalizzata</string>
|
||||
<string name="https_scheme_with_port_message">Sembra che tu stia usando un URL HTTPS con una porta personalizzata. Questo non è supportato e causerà problemi in futuro. Premere OK per rimuovere la porta dall\'URL.</string>
|
||||
<!-- Proxy configuration activity -->
|
||||
<string name="proxy_hostname">Nome host del proxy</string>
|
||||
<string name="port">Porta</string>
|
||||
<string name="pref_proxy_settings">Impostazioni proxy HTTP(S)</string>
|
||||
<string name="invalid_proxy_url">URL non valido</string>
|
||||
<string name="oreo_autofill_password_fill_and_conditional_save_support">Compila e salva le password (il salvataggio necessita che nessun servizio di accessibilità sia abilitato)</string>
|
||||
<string name="clear_saved_host_key">Cancella la chiave host salvata</string>
|
||||
<string name="clear_saved_host_key_success">Chiave host cancellata con successo!</string>
|
||||
</resources>
|
||||
|
|
8
app/src/nonFree/values-de/strings.xml
Normal file
8
app/src/nonFree/values-de/strings.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
~ SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<resources>
|
||||
<string name="oreo_autofill_waiting_for_sms">Warte auf SMS…</string>
|
||||
</resources>
|
8
app/src/nonFree/values-gl/strings.xml
Normal file
8
app/src/nonFree/values-gl/strings.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
~ SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<resources>
|
||||
<string name="oreo_autofill_waiting_for_sms">Agardando polo SMS…</string>
|
||||
</resources>
|
8
app/src/nonFree/values-it/strings.xml
Normal file
8
app/src/nonFree/values-it/strings.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
~ SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<resources>
|
||||
<string name="oreo_autofill_waiting_for_sms">In attesa del SMS…</string>
|
||||
</resources>
|
8
app/src/nonFree/values-pt-BR/strings.xml
Normal file
8
app/src/nonFree/values-pt-BR/strings.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
~ SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<resources>
|
||||
<string name="oreo_autofill_waiting_for_sms">Esperando pelo SMS…</string>
|
||||
</resources>
|
8
app/src/nonFree/values-ru/strings.xml
Normal file
8
app/src/nonFree/values-ru/strings.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
~ SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<resources>
|
||||
<string name="oreo_autofill_waiting_for_sms">Ожидание SMS…</string>
|
||||
</resources>
|
8
app/src/nonFree/values-uk/strings.xml
Normal file
8
app/src/nonFree/values-uk/strings.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
~ SPDX-License-Identifier: GPL-3.0-only
|
||||
-->
|
||||
<resources>
|
||||
<string name="oreo_autofill_waiting_for_sms">Очікування SMS…</string>
|
||||
</resources>
|
|
@ -21,6 +21,10 @@ gradlePlugin {
|
|||
id = "aps-plugin"
|
||||
implementationClass = "PasswordStorePlugin"
|
||||
}
|
||||
register("crowdin") {
|
||||
id = "crowdin-plugin"
|
||||
implementationClass = "CrowdinDownloadPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,4 +32,5 @@ dependencies {
|
|||
implementation(build.getValue("kotlinGradlePlugin"))
|
||||
implementation(build.getValue("androidGradlePlugin"))
|
||||
implementation(build.getValue("binaryCompatibilityValidator"))
|
||||
implementation(build.getValue("downloadTaskPlugin"))
|
||||
}
|
||||
|
|
|
@ -2,10 +2,12 @@ rootProject.ext.versions = [
|
|||
agp : '4.1.0',
|
||||
kotlin : '1.4.21',
|
||||
binary_compatibility_validator : '0.2.4',
|
||||
download_plugin : '4.1.1',
|
||||
]
|
||||
|
||||
rootProject.ext.build = [
|
||||
androidGradlePlugin : "com.android.tools.build:gradle:${versions.agp}",
|
||||
kotlinGradlePlugin : "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}",
|
||||
binaryCompatibilityValidator : "org.jetbrains.kotlinx:binary-compatibility-validator:${versions.binary_compatibility_validator}",
|
||||
downloadTaskPlugin : "de.undercouch:gradle-download-task:${versions.download_plugin}",
|
||||
]
|
||||
|
|
76
buildSrc/src/main/java/CrowdinDownloadPlugin.kt
Normal file
76
buildSrc/src/main/java/CrowdinDownloadPlugin.kt
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
import de.undercouch.gradle.tasks.download.Download
|
||||
import java.io.File
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.Copy
|
||||
import org.gradle.kotlin.dsl.create
|
||||
import org.gradle.kotlin.dsl.register
|
||||
|
||||
class CrowdinDownloadPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(project: Project) {
|
||||
with(project) {
|
||||
val extension = extensions.create<CrowdinExtension>("crowdin")
|
||||
afterEvaluate {
|
||||
val projectName = extension.projectName
|
||||
if (projectName.isEmpty()) {
|
||||
throw GradleException(
|
||||
"""
|
||||
Applying `crowdin-plugin` requires a projectName to be configured via the "crowdin" extension.
|
||||
""".trimIndent()
|
||||
)
|
||||
}
|
||||
tasks.register<Download>("downloadCrowdin") {
|
||||
src("https://crowdin.com/backend/download/project/$projectName.zip")
|
||||
dest("$buildDir/translations.zip")
|
||||
overwrite(true)
|
||||
}
|
||||
tasks.register<Copy>("extractCrowdin") {
|
||||
setDependsOn(setOf("downloadCrowdin"))
|
||||
doFirst {
|
||||
File(buildDir, "translations").deleteRecursively()
|
||||
}
|
||||
from(zipTree("$buildDir/translations.zip"))
|
||||
into("$buildDir/translations")
|
||||
}
|
||||
tasks.register<Copy>("extractBaseStrings") {
|
||||
setDependsOn(setOf("extractCrowdin"))
|
||||
from("$buildDir/translations/${project.name}/src/main/res")
|
||||
into("${projectDir}/src/main/res")
|
||||
}
|
||||
tasks.register<Copy>("extractNonFreeStrings") {
|
||||
setDependsOn(setOf("extractCrowdin"))
|
||||
from("$buildDir/translations/") {
|
||||
exclude("app/")
|
||||
}
|
||||
into("$buildDir/nonFree-translations")
|
||||
doLast {
|
||||
File("$buildDir/nonFree-translations")
|
||||
.listFiles { file: File -> file.isDirectory }?.forEach { file ->
|
||||
val dest = File("${projectDir}/src/nonFree/values-${file.name}")
|
||||
val src = File(file, "app/src/nonFree/res/values/strings.xml")
|
||||
dest.mkdirs()
|
||||
src.renameTo(File(dest, "strings.xml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks.register("crowdin") {
|
||||
setDependsOn(setOf("extractBaseStrings", "extractNonFreeStrings"))
|
||||
if (!extension.skipCleanup) {
|
||||
doLast {
|
||||
File("$buildDir/translations").deleteRecursively()
|
||||
File("$buildDir/nonFree-translations").deleteRecursively()
|
||||
File("$buildDir/translations.zip").delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
buildSrc/src/main/java/CrowdinExtension.kt
Normal file
19
buildSrc/src/main/java/CrowdinExtension.kt
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved.
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
open class CrowdinExtension {
|
||||
|
||||
/**
|
||||
* Configure the project name on Crowdin
|
||||
*/
|
||||
open var projectName = ""
|
||||
|
||||
/**
|
||||
* Don't delete downloaded and extracted translation archives from build directory.
|
||||
*
|
||||
* Useful for debugging.
|
||||
*/
|
||||
open var skipCleanup = false
|
||||
}
|
Loading…
Reference in a new issue