Skip to content

Commit

Permalink
check: pin flutter version
Browse files Browse the repository at this point in the history
* Introduce a git submodule to pin the version of flutter SDK under
  `vendor/flutter`.
* Use direnv to add `vendor/flutter/bin` to the current PATH so that
  subsequent calls to `flutter` on the shell uses the our pinned
  version of flutter.
* Update instructions to use pinned version of flutter.
* Pin to 18340ea16c of flutter which matches the current lowerbound
version in pubsec.yaml (3.21.0-12.0.pre.26).

NOTE: Users can still choose to opt-out and use their own version of
flutter. This just provides a recommended and tested version on our
CI.

Closes zulip#15
  • Loading branch information
chrisirhc committed Mar 26, 2024
1 parent 9044a9a commit dee608b
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 20 deletions.
5 changes: 5 additions & 0 deletions .envrc
@@ -0,0 +1,5 @@
# This file is used by direnv to setup the environment when entering
# to use vendored flutter SDK.

# Comment out the next line if you want to use your system flutter.
PATH_add vendor/flutter/bin
24 changes: 18 additions & 6 deletions .github/workflows/ci.yml
Expand Up @@ -6,17 +6,29 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Checkout repository
uses: actions/checkout@v3

- name: Clone Flutter SDK
- name: Checkout flutter submodule
# We can't do a depth-1 clone, because we need the most recent tag
# so that Flutter knows its version and sees the constraint in our
# pubspec is satisfied. It's uncommon for flutter/flutter to go
# more than 100 commits between tags. Fetch 1000 for good measure.
# more than 100 commits between tags. Fetch 1000 for good measure.
# This is also why we don't use the `with submodules` in the
# `checkout` action.
run: |
git clone --depth=1000 https://github.com/flutter/flutter ~/flutter
TZ=UTC git --git-dir ~/flutter/.git log -1 --format='%h | %ci | %s' --date=iso8601-local
echo ~/flutter/bin >> "$GITHUB_PATH"
git submodule update --init --depth 1000
- name: Add vendored flutter to PATH
run: |
echo vendor/flutter/bin >> "$GITHUB_PATH"
- name: Run setup
run: tools/setup-vendor-flutter

- name: Display version (Temporary)
run: |
flutter --version
- name: Download Flutter SDK artifacts (flutter precache)
run: flutter precache --universal
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
@@ -0,0 +1,4 @@
[submodule "vendor/flutter"]
path = vendor/flutter
url = https://github.com/flutter/flutter.git
branch = main
1 change: 1 addition & 0 deletions .vscode/settings.json
Expand Up @@ -17,4 +17,5 @@

// This much more focused automatic fix is helpful, though.
"files.trimTrailingWhitespace": true,
"dart.flutterSdkPaths": ["vendor/flutter"],
}
79 changes: 65 additions & 14 deletions README.md
Expand Up @@ -92,26 +92,74 @@ Two specific points to expand on:

### Setting up

1. Follow the [Flutter installation guide](https://docs.flutter.dev/get-started/install)
for your platform of choice.
2. Switch to the latest version of Flutter by running `flutter channel main`
and `flutter upgrade` (see [Flutter version](#flutter-version) below).
3. Ensure Flutter is correctly configured by running `flutter doctor`.
4. Start the app with `flutter run`, or from your IDE.
1. Setup the pinned version of flutter.
(See [Flutter version](#flutter-version) for details on what this
step does and read it if you want to use your own version of
flutter.)

1.1. Make sure you have initialized submodule by doing (do
not do `--depth=1` as flutter relies on tags to know its version):

```sh
# Update and initialize submodule
git submodule update --init
# Run setup-vendor-flutter
./tools/setup-vendor-flutter
```

1.2. Install [direnv][direnv], and set up its hook:

```sh
# For MacOS users, you can use Homebrew:
brew install direnv

# For Linux users, direnv is typically distributed as a package,
# so you can use apt-get (see direnv website for distro-specific
# instructions if this doesn't work):
sudo apt install direnv

# After installation, make sure to run this in the zulip-flutter
# directory to allow the .envrc file.
direnv allow
```
2. Ensure Flutter is correctly configured by running `flutter doctor`.
3. Start the app with `flutter run`, or from your IDE.
If you're using VSCode, you're set.
If you're using Android Studio, please read the next step.

3.1 For Android Studio users only (unless you are using your own
custom version of flutter):

After you first open, the project, go to:
`Settings -> Languages & Frameworks -> Flutter`
Under `Flutter SDK Path`, enter `<REPO_DIR>/vendor/flutter` (where
`<REPO_DIR>` is the location of the checkout of the repo).


### Flutter version

While in the beta phase, we use the latest Flutter from Flutter's
main branch. Use `flutter channel main` and `flutter upgrade`.
We pin to a particular version of flutter SDK via git submodules in
[vendor/flutter/](vendor/flutter/).
If your local checkout of this repository does not have this submodule
checked out at the same commit, the build may fail.

We don't pin a specific version, because Flutter itself doesn't offer
a way to do so. So far that hasn't been a problem. When it becomes one,
we'll figure it out; there are several tools for this in the Flutter
community. See [issue #15][].
However, if you want to manage your own flutter SDK version you can
opt out of this behavior by either of:
- Skip installing direnv or don't do `direnv allow`.
- Comment out the lines in `.envrc`.

[issue #15]: https://github.com/zulip/zulip-flutter/issues/15
Do note that if you do this, you need to manually make sure that the
flutter SDK version matches or is compatible with the version
indicated by the submodule commit SHA.

Otherwise, the build can fail as we have not tested the current code
with that particular flutter SDK version.

If you want manage your own flutter SDK version, follow the [Flutter
installation guide](https://docs.flutter.dev/get-started/install) for
your platform of choice.

[direnv]: https://direnv.net/

### Tests

Expand Down Expand Up @@ -242,13 +290,16 @@ that's a good prompt to do this. We also do this when there's a
new PR merged that we particularly want to take.

To update the version bounds:
* First, make sure you're on the `main` channel, run:
`flutter channel main`.
* Use `flutter upgrade` to upgrade your local Flutter and Dart.
* Update the lower bounds at `environment` in `pubspec.yaml`
to the new versions, as seen in `flutter --version`.
* Run `flutter pub get`, which will update `pubspec.lock`.
* Make a quick check that things work: `tools/check`,
and do a quick smoke-test of the app.
* Commit and push the changes in `pubspec.yaml` and `pubspec.lock`.
* Commit and push the changes in the submodule `vendor/flutter`,
`pubspec.yaml` and `pubspec.lock`.


### Upgrading dependencies
Expand Down
5 changes: 5 additions & 0 deletions analysis_options.yaml
Expand Up @@ -9,6 +9,11 @@
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

analyzer:
# Don't analyze code in the `vendor/` directory which contains the flutter
# SDK.
exclude: [vendor/**]

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
Expand Down
10 changes: 10 additions & 0 deletions tools/lib/git.sh
Expand Up @@ -90,3 +90,13 @@ git_base_commit() {
git_changed_files() {
git diff --name-only --diff-filter=d "$@"
}

# Note that this assumes ONE submodule. If we ever have more than one,
# we'll need to generalize this.
submodule_is_clean()
{
# first character of every line status indicates the status of the
# submodule. If there is a space, it means the submodule is clean
# and initiated.
git submodule status | grep -q "^ "
}
19 changes: 19 additions & 0 deletions tools/setup
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail

this_dir=${BASH_SOURCE[0]%/*}

# shellcheck source=tools/lib/git.sh
. "${this_dir}"/lib/git.sh


# One-time setup to let git submodule + flutter SDK know that we're
# using the main channel (main branch).
# We should do a quick check that there's no changes.
if ! submodule_is_clean; then
echo >&2 "There are changes in the submodule or it is not initialized."
echo >&2 "Please run 'git submodule update --init' then run this script again."
exit 1
fi

git -C vendor/flutter checkout -B main HEAD
1 change: 1 addition & 0 deletions vendor/flutter
Submodule flutter added at 18340e

0 comments on commit dee608b

Please sign in to comment.