Merge branch 'ci_setup'

This commit is contained in:
Grishka 2024-03-06 15:59:19 +03:00
commit f0295edd83
19 changed files with 202 additions and 15 deletions

80
.github/workflows/build_and_deploy.yml vendored Normal file
View File

@ -0,0 +1,80 @@
name: Build and deploy
on:
push:
branches:
- 'ci_setup'
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: 21
distribution: temurin
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7.2
bundler-cache: true
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: Decode keystore
uses: timheuer/base64-to-file@v1
id: android_keystore
with:
fileName: "release.jks"
encodedString: ${{ secrets.KEYSTORE_FILE }}
- name: Prepare Gradle environment
run: |
echo "apply from: 'ci_signing.gradle'" >> mastodon/build.gradle
echo "sdk.dir=$ANDROID_SDK_ROOT" > local.properties
- name: Build and deploy to Google Play
run: bundle exec fastlane deploy
env:
KEYSTORE_FILE: ${{ steps.android_keystore.outputs.filePath }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
SUPPLY_JSON_KEY_DATA: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_KEY }}
SUPPLY_VALIDATE_ONLY: true
SUPPLY_SKIP_UPLOAD_METADATA: true
SUPPLY_SKIP_UPLOAD_CHANGELOGS: true
- name: Build release apk
run: ./gradlew assembleRelease
env:
KEYSTORE_FILE: ${{ steps.android_keystore.outputs.filePath }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
- name: Upload release apk
uses: actions/upload-artifact@v4
with:
name: mastodon-release.apk
path: mastodon/build/outputs/apk/release/mastodon-release.apk
- name: Build githubRelease apk
run: ./gradlew assembleGithubRelease
env:
KEYSTORE_FILE: ${{ steps.android_keystore.outputs.filePath }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
- name: Upload githubRelease apk
uses: actions/upload-artifact@v4
with:
name: mastodon-githubRelease.apk
path: mastodon/build/outputs/apk/githubRelease/mastodon-githubRelease.apk
- name: Upload mappings
uses: actions/upload-artifact@v4
with:
name: mappings
path: mastodon/build/outputs/mapping/*/mapping.txt

1
.gitignore vendored
View File

@ -9,3 +9,4 @@
.cxx .cxx
local.properties local.properties
*.jks *.jks
/fastlane/report.xml

3
Gemfile Normal file
View File

@ -0,0 +1,3 @@
source "https://rubygems.org"
gem "fastlane"

View File

@ -5,7 +5,7 @@ buildscript {
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath "com.android.tools.build:gradle:7.4.2" classpath "com.android.tools.build:gradle:8.2.2"
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1" classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

2
fastlane/Appfile Normal file
View File

@ -0,0 +1,2 @@
json_key_file("") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("org.joinmastodon.android") # e.g. com.krausefx.app

36
fastlane/Fastfile Normal file
View File

@ -0,0 +1,36 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:android)
platform :android do
desc "Runs all the tests"
lane :test do
gradle(task: "test")
end
desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(
task: "bundle",
build_type: "release",
)
upload_to_play_store(
changes_not_sent_for_review: true,
skip_upload_images: true,
skip_upload_screenshots: true
)
end
end

40
fastlane/README.md Normal file
View File

@ -0,0 +1,40 @@
fastlane documentation
----
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```sh
xcode-select --install
```
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
# Available Actions
## Android
### android test
```sh
[bundle exec] fastlane android test
```
Runs all the tests
### android deploy
```sh
[bundle exec] fastlane android deploy
```
Deploy a new version to the Google Play
----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

View File

@ -0,0 +1,3 @@
- You can now easily share and scan QR codes to quickly find each other
- We've updated the look of the tab bar to better match current platform guidelines
- Various minor usability improvements

View File

@ -1,6 +1,6 @@
#Sat Jun 03 23:40:27 MSK 2023 #Sat Jun 03 23:40:27 MSK 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -66,6 +66,7 @@ android {
} }
buildFeatures{ buildFeatures{
aidl true aidl true
buildConfig true
} }
dependenciesInfo{ dependenciesInfo{
// Disables dependency metadata when building APKs. // Disables dependency metadata when building APKs.
@ -73,6 +74,7 @@ android {
// Disables dependency metadata when building Android App Bundles. // Disables dependency metadata when building Android App Bundles.
includeInBundle false includeInBundle false
} }
namespace 'org.joinmastodon.android'
} }
dependencies { dependencies {

View File

@ -0,0 +1,20 @@
// Included into build.gradle when running in a CI pipeline
android{
signingConfigs{
release{
keyAlias "key0"
keyPassword System.getenv("KEYSTORE_PASSWORD")
storeFile file(System.getenv("KEYSTORE_FILE"))
storePassword System.getenv("KEYSTORE_PASSWORD")
}
}
buildTypes{
release{
signingConfig signingConfigs.release
}
githubRelease{
signingConfig signingConfigs.release
}
}
}

View File

@ -112,7 +112,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
content.setOrientation(LinearLayout.VERTICAL); content.setOrientation(LinearLayout.VERTICAL);
FrameLayout fragmentContainer=new FrameLayout(getActivity()); FrameLayout fragmentContainer=new FrameLayout(getActivity());
fragmentContainer.setId(R.id.fragment_wrap); fragmentContainer.setId(me.grishka.appkit.R.id.fragment_wrap);
content.addView(fragmentContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f)); content.addView(fragmentContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
inflater.inflate(R.layout.tab_bar, content); inflater.inflate(R.layout.tab_bar, content);
@ -131,10 +131,10 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
if(savedInstanceState==null){ if(savedInstanceState==null){
getChildFragmentManager().beginTransaction() getChildFragmentManager().beginTransaction()
.add(R.id.fragment_wrap, homeTimelineFragment) .add(me.grishka.appkit.R.id.fragment_wrap, homeTimelineFragment)
.add(R.id.fragment_wrap, searchFragment).hide(searchFragment) .add(me.grishka.appkit.R.id.fragment_wrap, searchFragment).hide(searchFragment)
.add(R.id.fragment_wrap, notificationsFragment).hide(notificationsFragment) .add(me.grishka.appkit.R.id.fragment_wrap, notificationsFragment).hide(notificationsFragment)
.add(R.id.fragment_wrap, profileFragment).hide(profileFragment) .add(me.grishka.appkit.R.id.fragment_wrap, profileFragment).hide(profileFragment)
.commit(); .commit();
String defaultTab=getArguments().getString("tab"); String defaultTab=getArguments().getString("tab");

View File

@ -310,7 +310,7 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState){ public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState){
super.onSelectedChanged(viewHolder, actionState); super.onSelectedChanged(viewHolder, actionState);
if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){ if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
viewHolder.itemView.setTag(R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw() viewHolder.itemView.setTag(me.grishka.appkit.R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw()
viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start(); viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
} }
} }

View File

@ -930,7 +930,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
Toolbar toolbar=getToolbar(); Toolbar toolbar=getToolbar();
if(canGoBack()){ if(canGoBack()){
Drawable back=getToolbarContext().getDrawable(R.drawable.ic_arrow_back).mutate(); Drawable back=getToolbarContext().getDrawable(me.grishka.appkit.R.drawable.ic_arrow_back).mutate();
back.setTint(UiUtils.getThemeColor(getToolbarContext(), R.attr.colorM3OnSurfaceVariant)); back.setTint(UiUtils.getThemeColor(getToolbarContext(), R.attr.colorM3OnSurfaceVariant));
toolbar.setNavigationIcon(back); toolbar.setNavigationIcon(back);
toolbar.setNavigationContentDescription(0); toolbar.setNavigationContentDescription(0);

View File

@ -180,7 +180,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
searchBack.setImportantForAccessibility(searchActive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES : View.IMPORTANT_FOR_ACCESSIBILITY_NO); searchBack.setImportantForAccessibility(searchActive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES : View.IMPORTANT_FOR_ACCESSIBILITY_NO);
searchBack.setOnClickListener(v->exitSearch()); searchBack.setOnClickListener(v->exitSearch());
if(searchActive){ if(searchActive){
searchBack.setImageResource(R.drawable.ic_arrow_back); searchBack.setImageResource(me.grishka.appkit.R.drawable.ic_arrow_back);
pager.setVisibility(View.GONE); pager.setVisibility(View.GONE);
tabLayout.setVisibility(View.GONE); tabLayout.setVisibility(View.GONE);
searchView.setVisibility(View.VISIBLE); searchView.setVisibility(View.VISIBLE);
@ -228,7 +228,7 @@ public class DiscoverFragment extends AppKitFragment implements ScrollableToTop,
pager.setVisibility(View.GONE); pager.setVisibility(View.GONE);
tabLayout.setVisibility(View.GONE); tabLayout.setVisibility(View.GONE);
searchView.setVisibility(View.VISIBLE); searchView.setVisibility(View.VISIBLE);
searchBack.setImageResource(R.drawable.ic_arrow_back); searchBack.setImageResource(me.grishka.appkit.R.drawable.ic_arrow_back);
searchBack.setEnabled(true); searchBack.setEnabled(true);
searchBack.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); searchBack.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
tabsDivider.setVisibility(View.GONE); tabsDivider.setVisibility(View.GONE);

View File

@ -166,7 +166,7 @@ public class SearchQueryFragment extends MastodonRecyclerFragment<SearchResultVi
navigationIcon=new LayerDrawable(new Drawable[]{ navigationIcon=new LayerDrawable(new Drawable[]{
searchIcon=getToolbarContext().getResources().getDrawable(R.drawable.ic_search_24px, getToolbarContext().getTheme()).mutate(), searchIcon=getToolbarContext().getResources().getDrawable(R.drawable.ic_search_24px, getToolbarContext().getTheme()).mutate(),
backIcon=getToolbarContext().getResources().getDrawable(R.drawable.ic_arrow_back, getToolbarContext().getTheme()).mutate() backIcon=getToolbarContext().getResources().getDrawable(me.grishka.appkit.R.drawable.ic_arrow_back, getToolbarContext().getTheme()).mutate()
}){ }){
@Override @Override
public Drawable mutate(){ public Drawable mutate(){

View File

@ -63,7 +63,7 @@ public class PhotoViewerInfoSheet extends BottomSheet{
} }
backButton=new ImageButton(context); backButton=new ImageButton(context);
backButton.setImageResource(R.drawable.ic_arrow_back); backButton.setImageResource(me.grishka.appkit.R.drawable.ic_arrow_back);
backButton.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(context, R.attr.colorM3OnSurfaceVariant))); backButton.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(context, R.attr.colorM3OnSurfaceVariant)));
backButton.setBackgroundResource(R.drawable.bg_button_m3_tonal_icon); backButton.setBackgroundResource(R.drawable.bg_button_m3_tonal_icon);
backButton.setOutlineProvider(ViewOutlineProvider.BACKGROUND); backButton.setOutlineProvider(ViewOutlineProvider.BACKGROUND);

View File

@ -53,7 +53,7 @@ public abstract class DropdownSubmenuController{
backItem=(TextView) dropdownController.getActivity().getLayoutInflater().inflate(R.layout.item_dropdown_menu, contentView, false); backItem=(TextView) dropdownController.getActivity().getLayoutInflater().inflate(R.layout.item_dropdown_menu, contentView, false);
((LinearLayout.LayoutParams) backItem.getLayoutParams()).topMargin=V.dp(8); ((LinearLayout.LayoutParams) backItem.getLayoutParams()).topMargin=V.dp(8);
backItem.setText(backTitle); backItem.setText(backTitle);
backItem.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_arrow_back, 0, 0, 0); backItem.setCompoundDrawablesRelativeWithIntrinsicBounds(me.grishka.appkit.R.drawable.ic_arrow_back, 0, 0, 0);
backItem.setBackground(UiUtils.getThemeDrawable(dropdownController.getActivity(), android.R.attr.selectableItemBackground)); backItem.setBackground(UiUtils.getThemeDrawable(dropdownController.getActivity(), android.R.attr.selectableItemBackground));
backItem.setOnClickListener(v->dropdownController.popSubmenuController()); backItem.setOnClickListener(v->dropdownController.popSubmenuController());
backItem.setAccessibilityDelegate(new View.AccessibilityDelegate(){ backItem.setAccessibilityDelegate(new View.AccessibilityDelegate(){

View File

@ -284,7 +284,7 @@ public class ReorderableLinearLayout extends LinearLayout implements CustomViewH
private int getMaxDragScroll(){ private int getMaxDragScroll(){
if(cachedMaxScrollSpeed==-1){ if(cachedMaxScrollSpeed==-1){
cachedMaxScrollSpeed=getResources().getDimensionPixelSize(R.dimen.item_touch_helper_max_drag_scroll_per_frame); cachedMaxScrollSpeed=getResources().getDimensionPixelSize(me.grishka.appkit.R.dimen.item_touch_helper_max_drag_scroll_per_frame);
} }
return cachedMaxScrollSpeed; return cachedMaxScrollSpeed;
} }