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 #15
  • Loading branch information
chrisirhc authored and gnprice committed Apr 30, 2024
1 parent fcd74e6 commit e9d04ea
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -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
20 changes: 14 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,25 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check out repository
uses: actions/checkout@v3
# We're not using `with: submodules` here because we can't do a
# depth=1 clone. See below for more details.

- 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.
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: Download Flutter SDK artifacts (flutter precache)
run: flutter precache --universal
Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@

// This much more focused automatic fix is helpful, though.
"files.trimTrailingWhitespace": true,
"dart.flutterSdkPaths": ["vendor/flutter"],
}
80 changes: 66 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,75 @@ 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.

1.1. Make sure you have initialized submodule by doing:

```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
# On Debian or Ubuntu (bash):
sudo apt install direnv && echo 'eval "$(direnv hook bash)"' >>~/.bashrc
# Or using Homebrew:
brew install direnv
# Or see: https://direnv.net/docs/installation.html
# Then: https://direnv.net/docs/hook.html
# After installing and setting up the hook, run this in the zulip-flutter
# directory to allow the .envrc file.
direnv allow
```

1.3. Follow remaining instructions in [Flutter installation guide](https://docs.flutter.dev/get-started/install)
for your platform of choice. You can skip the Flutter SDK installation as that is now done.

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.
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`.

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.

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][].
Otherwise, the build can fail as we have not tested the current code
with that particular flutter SDK version.

[issue #15]: https://github.com/zulip/zulip-flutter/issues/15
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 +291,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
3 changes: 3 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ analyzer:
# TODO(pigeon) re-enable lints once clean: https://github.com/flutter/flutter/issues/145633
- lib/host/*.g.dart

# Skip analysis on `vendor/`, which has outside code like the Flutter SDK.
- vendor/**

linter:
# For a list of all available lints, with docs, see:
# https://dart-lang.github.io/linter/lints/index.html.
Expand Down
3 changes: 2 additions & 1 deletion tools/check
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ run_icons() {

run_shellcheck() {
# Omitted from this check: nothing (nothing known, anyway).
files_check tools/ '!*.'{dart,js,json} \
files_check tools/ '!*.'{dart,js,json} .envrc \
|| return 0

# Shellcheck is fast, <1s; so if we touched any possible targets at all,
Expand All @@ -362,6 +362,7 @@ run_shellcheck() {
targets=(
$(git grep -l '#!.*sh\b' -- tools/)
$(git ls-files -- tools/'*.sh')
.envrc
)

if ! type shellcheck >/dev/null 2>&1; then
Expand Down
10 changes: 10 additions & 0 deletions tools/lib/git.sh
Original file line number Diff line number Diff line change
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-vendor-flutter
Original file line number Diff line number Diff line change
@@ -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 "vendor/flutter" ; then
echo >&2 "There are changes in 'vendor/flutter' tree 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 e9d04ea

Please sign in to comment.