Fix frozen spinner (#61)

Fixes #60

The `late final` field isn't instantiated until it is read, so without
forcing instantiation in the constructor there is no timer updating the
display. Move initialization back into the constructor.

Other cleanup:
- Remove the `_index` fields since it is otherwise identical to
  `_timer.ticks`.
- Use a Github Action config that more closely matches our other
  packages.
- Replace `homepage` with `repository` in the pubspec.

There are no existing tests for the spinner, and adding one would be a
large task - this code was not written with testability in mind. For now
leave this untested.
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 36eb913..34a090a 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -1,35 +1,55 @@
-name: Dart
+name: Dart CI
 
 on:
   schedule:
     # “At 00:00 (UTC) on Sunday.”
     - cron: '0 0 * * 0'
   pull_request:
+    branches: [ master ]
   push:
-    branches:
-      - master
+    branches: [ master ]
+
+env:
+  PUB_ENVIRONMENT: bot.github
 
 jobs:
-  build:
+  analyze:
     runs-on: ubuntu-latest
-
-    container:
-      image:  google/dart:dev
-
+    strategy:
+      fail-fast: false
+      matrix:
+        sdk: [dev]
     steps:
-      - uses: actions/checkout@v2
+    - uses: actions/checkout@v2
+    - uses: dart-lang/setup-dart@v1
+      with:
+        sdk: ${{ matrix.sdk }}
+    - id: install
+      name: Install dependencies
+      run: dart pub get
+    - name: Check formatting
+      run: dart format --output=none --set-exit-if-changed .
+      if: always() && steps.install.outcome == 'success'
+    - name: Analyze code
+      run: dart analyze --fatal-infos
+      if: always() && steps.install.outcome == 'success'
 
-      - name: Print Dart version
-        run: dart --version
-
-      - name: pub get
-        run: pub get
-
-      - name: dart format
-        run: dart format --output=none --set-exit-if-changed .
-
-      - name: dart analyze
-        run: dart analyze --fatal-infos
-
-      - name: dart test
-        run: dart test
+  test:
+    needs: analyze
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest]
+        sdk: [2.12.0, dev]
+    steps:
+    - uses: actions/checkout@v2
+    - uses: dart-lang/setup-dart@v1
+      with:
+        sdk: ${{ matrix.sdk }}
+    - id: install
+      name: Install dependencies
+      run: dart pub get
+    - name: Run tests
+      run: dart test --test-randomize-ordering-seed=random
+      if: always() && steps.install.outcome == 'success'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 92a3b28..2cfde58 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.1
+
+- Fix a bug in `AnsiProgress` where the spinning character doesn't every update.
+
 ## 0.3.0
 
 - Stable null safety release.
diff --git a/lib/cli_logging.dart b/lib/cli_logging.dart
index cd3a72e..193c4d0 100644
--- a/lib/cli_logging.dart
+++ b/lib/cli_logging.dart
@@ -200,13 +200,12 @@
 
   final Ansi ansi;
 
-  int _index = 0;
-  late final _timer = Timer.periodic(Duration(milliseconds: 80), (t) {
-    _index++;
-    _updateDisplay();
-  });
+  late final Timer _timer;
 
   AnsiProgress(this.ansi, String message) : super(message) {
+    _timer = Timer.periodic(Duration(milliseconds: 80), (t) {
+      _updateDisplay();
+    });
     io.stdout.write('$message...  '.padRight(40));
     _updateDisplay();
   }
@@ -232,7 +231,7 @@
       bool cancelled = false,
       String? message,
       bool showTiming = false}) {
-    var char = kAnimationItems[_index % kAnimationItems.length];
+    var char = kAnimationItems[_timer.tick % kAnimationItems.length];
     if (isFinal || cancelled) {
       char = '';
     }
diff --git a/pubspec.yaml b/pubspec.yaml
index 9386c55..ce17496 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,10 +1,10 @@
 name: cli_util
-version: 0.3.0
+version: 0.3.1
 description: A library to help in building Dart command-line apps.
-homepage: https://github.com/dart-lang/cli_util
+repository: https://github.com/dart-lang/cli_util
 
 environment:
-  sdk: '>=2.12.0-0 <3.0.0'
+  sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
   meta: ^1.3.0