Add GitHub Actions workflow (#2802)

* Add GitHub Actions workflow

* Remove travis config

* Remove caching

* Apply latest changes to dart-lang workflow template

* Replace Travis badge

* Fix badge link

* Change test URL to use https://invalid-url.foo

Resolving pub.invalid results in a SERVFAIL rather than the expected
NXDOMAIN response on Azure (used by GitHub Actions).
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
new file mode 100644
index 0000000..c648878
--- /dev/null
+++ b/.github/workflows/test.yaml
@@ -0,0 +1,72 @@
+name: Dart CI
+
+on:
+  # Run CI on pushes to the main branch, and on PRs against main.
+  push:
+    branches: [ master ]
+  pull_request:
+    branches: [ master ]
+  schedule:
+    - cron: "0 0 * * 0"
+
+env:
+  PUB_ENVIRONMENT: bot.github
+  _PUB_TEST_SNAPSHOT: ${{ github.workspace }}/.dart_tool/pub.dart.snapshot.dart2
+  _TESTS_FILE: .dart_tool/test_files
+
+jobs:
+  # Check code formatting and static analysis on a single OS (linux)
+  # against Dart stable and dev.
+  analyze:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        sdk: [dev]
+    steps:
+      - uses: actions/checkout@v2
+      - uses: dart-lang/setup-dart@v0.1
+        with:
+          channel: ${{ 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
+        if: always() && steps.install.outcome == 'success'
+
+  # Run tests on a matrix consisting of three dimensions:
+  # 1. OS: mac, windows, linux
+  # 2. release channel: dev
+  # 3. shard: 0, 1, 2, 3, 4, 5, 6
+  test:
+    needs: analyze
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest, macos-latest, windows-latest]
+        sdk: [dev]
+        shard: [0, 1, 2, 3, 4, 5, 6]
+    steps:
+      - uses: actions/checkout@v2
+      - uses: dart-lang/setup-dart@v0.1
+        with:
+          channel: ${{ matrix.sdk }}
+      - name: Install dependencies
+        run: dart pub get
+      - name: Build snapshot
+        run: dart --snapshot=${{ env._PUB_TEST_SNAPSHOT }} bin/pub.dart
+      - name: Select tests
+        run: |
+          find test -name "*_test\\.dart" | sort > $_TESTS_FILE
+          (( tests_per_shard = ($(wc -l <$_TESTS_FILE) + 7 - 1) / 7 ))
+          (( offset = 1 + tests_per_shard * ${{ matrix.shard }} ))
+          tail -n+$offset $_TESTS_FILE | head -n$tests_per_shard > $_TESTS_FILE.${{ matrix.shard }}
+        shell: bash
+      - name: Run tests
+        run: dart test --preset travis $(cat $_TESTS_FILE.${{ matrix.shard }})
+        shell: bash
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index a73b953..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-language: dart
-
-dart:
-  - dev
-
-os:
-  - linux
-  - osx
-  - windows
-
-addons:
-  homebrew:
-    packages:
-    - coreutils
-
-env:
-  global:
-    - SPLIT=`which gsplit || which split`
-    - _PUB_TEST_SNAPSHOT="`pwd`/.dart_tool/pub.dart.snapshot.dart2"
-
-dart_task:
-  - test: --preset travis `$SPLIT -n l/1/7 .dart_tool/test_files`
-  - test: --preset travis `$SPLIT -n l/2/7 .dart_tool/test_files`
-  - test: --preset travis `$SPLIT -n l/3/7 .dart_tool/test_files`
-  - test: --preset travis `$SPLIT -n l/4/7 .dart_tool/test_files`
-  - test: --preset travis `$SPLIT -n l/5/7 .dart_tool/test_files`
-  - test: --preset travis `$SPLIT -n l/6/7 .dart_tool/test_files`
-  - test: --preset travis `$SPLIT -n l/7/7 .dart_tool/test_files`
-
-jobs:
-  include:
-  - dart: dev
-    os: linux
-    dart_task: dartfmt
-  - dart: dev
-    os: linux
-    dart_task:
-      dartanalyzer: --fatal-infos --fatal-warnings .
-
-# Create a snapshot to improve startup time. Tests will automatically use this
-# snapshot if it's available.
-before_script:
-  - dart --snapshot="$_PUB_TEST_SNAPSHOT" bin/pub.dart
-  - find test -name "*_test\\.dart" | sort > .dart_tool/test_files
-
-# Only building these branches means that we don't run two builds for each pull
-# request.
-branches:
-  only: [master, travis, /^feature\./]
-
-cache:
-  directories:
-    - $HOME/.pub-cache
diff --git a/README.md b/README.md
index e3e6137..0137d74 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/dart-lang/pub.svg?branch=master)](https://travis-ci.org/dart-lang/pub)
+[![Build Status](https://github.com/dart-lang/pub/workflows/Dart%20CI/badge.svg)](https://github.com/dart-lang/pub/actions?query=workflow%3A"Dart+CI")
 
 Pub is the package manager for Dart.
 
diff --git a/test/hosted/fail_gracefully_on_url_resolve_test.dart b/test/hosted/fail_gracefully_on_url_resolve_test.dart
index 5f26616..ee93cb9 100644
--- a/test/hosted/fail_gracefully_on_url_resolve_test.dart
+++ b/test/hosted/fail_gracefully_on_url_resolve_test.dart
@@ -15,13 +15,13 @@
       await d.dir(appPath, [
         d.appPubspec({
           'foo': {
-            'hosted': {'name': 'foo', 'url': 'http://pub.invalid'}
+            'hosted': {'name': 'foo', 'url': 'https://invalid-url.foo'}
           }
         })
       ]).create();
 
       await pubCommand(command,
-          error: 'Could not resolve URL "http://pub.invalid".',
+          error: 'Could not resolve URL "https://invalid-url.foo".',
           exitCode: exit_codes.UNAVAILABLE,
           environment: {
             'PUB_MAX_HTTP_RETRIES': '2',