Bump target frameworks of C# programs from netcoreapp1.0 to netcoreapp2.1 (#5838)

* Bump target frameworks from netcoreapp1.0 to netcoreapp2.2.
Move global.json up to root of repo, change SDK ver to 2.2.100
Change .net core sdk in dockerfile for kokoro to ver 2.2.100

* Re-add curl install

* Change all exe target to 2.1

* Fix incorrect versions in global.json and Dockerfile

* Downgrade version to 2.1 to match exe targets

* introduce separate testing Dockerfile for C#

* revert changes to the shared Dockerfile

* use netcoreapp2.1 for C# conformance tests

* use language specific dockerfile for testing C#

* Edit compatibility tests script to use parameters instead of file copies

* install dotnet SDK on windows before running the tests

* update csharp_EXTRA_DIST
diff --git a/Makefile.am b/Makefile.am
index 6784dd0..faf236d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@
 pkgconfig_DATA = protobuf.pc protobuf-lite.pc
 
 csharp_EXTRA_DIST=                                                           \
+  global.json                                                                \
   csharp/.gitignore                                                          \
   csharp/CHANGES.txt                                                         \
   csharp/Google.Protobuf.Tools.targets                                       \
@@ -58,7 +59,7 @@
   csharp/build_tools.sh                                                      \
   csharp/buildall.sh                                                         \
   csharp/generate_protos.sh                                                  \
-  csharp/global.json                                                         \
+  csharp/install_dotnet_sdk.ps1                                              \
   csharp/keys/Google.Protobuf.public.snk                                     \
   csharp/keys/Google.Protobuf.snk                                            \
   csharp/keys/README.md                                                      \
diff --git a/conformance/Makefile.am b/conformance/Makefile.am
index 18ac673..f2337df 100644
--- a/conformance/Makefile.am
+++ b/conformance/Makefile.am
@@ -316,7 +316,7 @@
 conformance-csharp: $(other_language_protoc_outputs)
 	@echo "Writing shortcut script conformance-csharp..."
 	@echo '#! /bin/sh' > conformance-csharp
-	@echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp1.0/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp
+	@echo 'dotnet ../csharp/src/Google.Protobuf.Conformance/bin/Release/netcoreapp2.1/Google.Protobuf.Conformance.dll "$$@"' >> conformance-csharp
 	@chmod +x conformance-csharp
 
 conformance-php:
diff --git a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
index 6bc1e0c..1ef5bf8 100644
--- a/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+++ b/csharp/compatibility_tests/v3.0.0/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <TargetFrameworks>net451;netcoreapp1.0</TargetFrameworks>
+    <TargetFrameworks>net451;netcoreapp2.1</TargetFrameworks>
     <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
     <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
@@ -24,7 +24,7 @@
     - Visual Studio.
     -->
   <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
-    <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+    <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
   </PropertyGroup>
 
 </Project>
diff --git a/csharp/compatibility_tests/v3.0.0/test.sh b/csharp/compatibility_tests/v3.0.0/test.sh
index 54d28df..9fcf406 100755
--- a/csharp/compatibility_tests/v3.0.0/test.sh
+++ b/csharp/compatibility_tests/v3.0.0/test.sh
@@ -2,17 +2,17 @@
 
 function run_test() {
   # Generate test proto files.
-  ./protoc_1 -Iprotos/src -I../../../src/ --csharp_out=src/Google.Protobuf.Test \
+  $1 -Iprotos/src -I../../../src/ --csharp_out=src/Google.Protobuf.Test \
     --csharp_opt=base_namespace=Google.Protobuf \
     protos/src/google/protobuf/unittest_import_proto3.proto \
     protos/src/google/protobuf/unittest_import_public_proto3.proto \
     protos/src/google/protobuf/unittest_well_known_types.proto
 
-  ./protoc_1 -Iprotos/csharp --csharp_out=src/Google.Protobuf.Test \
+  $1 -Iprotos/csharp --csharp_out=src/Google.Protobuf.Test \
     --csharp_opt=base_namespace=UnitTest.Issues \
     protos/csharp/protos/unittest_issues.proto
 
-  ./protoc_2 -Iprotos/src --csharp_out=src/Google.Protobuf.Test \
+  $2 -Iprotos/src --csharp_out=src/Google.Protobuf.Test \
     --csharp_opt=base_namespace=Google.Protobuf \
     protos/src/google/protobuf/unittest_proto3.proto \
     protos/src/google/protobuf/map_unittest_proto3.proto
@@ -22,7 +22,7 @@
   dotnet restore src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
   dotnet build -c Release src/Google.Protobuf/Google.Protobuf.csproj
   dotnet build -c Release src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
-  dotnet run -c Release -f netcoreapp1.0 -p src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+  dotnet run -c Release -f netcoreapp2.1 -p src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
 }
 
 set -ex
@@ -79,26 +79,18 @@
 # Test A.1:
 #   proto set 1: use old version
 #   proto set 2 which may import protos in set 1: use old version
-cp old_protoc protoc_1
-cp old_protoc protoc_2
-run_test
+run_test "./old_protoc" "./old_protoc"
 
 # Test A.2:
 #   proto set 1: use new version
 #   proto set 2 which may import protos in set 1: use old version
-cp ../../../src/protoc protoc_1
-cp old_protoc protoc_2
-run_test
+run_test "../../../src/protoc" "./old_protoc"
 
 # Test A.3:
 #   proto set 1: use old version
 #   proto set 2 which may import protos in set 1: use new version
-cp old_protoc protoc_1
-cp ../../../src/protoc protoc_2
-run_test
+run_test "./old_protoc" "../../../src/protoc"
 
-rm protoc_1
-rm protoc_2
 rm old_protoc
 rm keys -r
 rm src/Google.Protobuf -r
diff --git a/csharp/global.json b/csharp/global.json
deleted file mode 100644
index 080dcb9..0000000
--- a/csharp/global.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "sdk": {
-    "version": "2.1.3"
-  }
-}
diff --git a/csharp/install_dotnet_sdk.ps1 b/csharp/install_dotnet_sdk.ps1
new file mode 100644
index 0000000..b4132ab
--- /dev/null
+++ b/csharp/install_dotnet_sdk.ps1
@@ -0,0 +1,21 @@
+#!/usr/bin/env powershell
+# Install dotnet SDK based on the SDK version from global.json
+
+Set-StrictMode -Version 2
+$ErrorActionPreference = 'Stop'
+
+# avoid "Unknown error on a send" in Invoke-WebRequest
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+
+$InstallScriptUrl = 'https://dot.net/v1/dotnet-install.ps1'
+$InstallScriptPath = Join-Path  "$env:TEMP" 'dotnet-install.ps1'
+$GlobalJsonPath = Join-Path $PSScriptRoot '..' | Join-Path -ChildPath 'global.json'
+
+# Resolve SDK version from global.json file
+$GlobalJson = Get-Content -Raw $GlobalJsonPath | ConvertFrom-Json
+$SDKVersion = $GlobalJson.sdk.version
+
+# Download install script
+Write-Host "Downloading install script: $InstallScriptUrl => $InstallScriptPath"
+Invoke-WebRequest -Uri $InstallScriptUrl -OutFile $InstallScriptPath
+&$InstallScriptPath -Version $SDKVersion
diff --git a/csharp/src/AddressBook/AddressBook.csproj b/csharp/src/AddressBook/AddressBook.csproj
index 6edfdca..f3268c0 100644
--- a/csharp/src/AddressBook/AddressBook.csproj
+++ b/csharp/src/AddressBook/AddressBook.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
     <OutputType>Exe</OutputType>
     <StartupObject>Google.Protobuf.Examples.AddressBook.Program</StartupObject>
     <IsPackable>False</IsPackable>
diff --git a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
index b654c0b..ec8fb91 100644
--- a/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
+++ b/csharp/src/Google.Protobuf.Conformance/Google.Protobuf.Conformance.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
     <OutputType>Exe</OutputType>
     <IsPackable>False</IsPackable>
   </PropertyGroup>
diff --git a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
index 4eda641..fee35be 100644
--- a/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
+++ b/csharp/src/Google.Protobuf.JsonDump/Google.Protobuf.JsonDump.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp1.0</TargetFramework>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
     <OutputType>Exe</OutputType>
     <IsPackable>False</IsPackable>
   </PropertyGroup>
diff --git a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
index 11adb11..32bb26c 100644
--- a/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
+++ b/csharp/src/Google.Protobuf.Test/Google.Protobuf.Test.csproj
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
-    <TargetFrameworks>net451;netcoreapp1.0</TargetFrameworks>
+    <TargetFrameworks>net451;netcoreapp2.1</TargetFrameworks>
     <AssemblyOriginatorKeyFile>../../keys/Google.Protobuf.snk</AssemblyOriginatorKeyFile>
     <SignAssembly>true</SignAssembly>
     <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
@@ -24,7 +24,7 @@
     - Visual Studio.
     -->
   <PropertyGroup Condition="'$(OS)' != 'Windows_NT'">
-    <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+    <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
   </PropertyGroup>
 
   <ItemGroup>
diff --git a/global.json b/global.json
new file mode 100644
index 0000000..0c7cc9f
--- /dev/null
+++ b/global.json
@@ -0,0 +1,5 @@
+{
+  "sdk": {
+    "version": "2.1.504"
+  }
+}
diff --git a/kokoro/linux/csharp/build.sh b/kokoro/linux/csharp/build.sh
index 27cb549..9a2eb48 100755
--- a/kokoro/linux/csharp/build.sh
+++ b/kokoro/linux/csharp/build.sh
@@ -10,7 +10,8 @@
 # Change to repo root
 cd $(dirname $0)/../../..
 
-export DOCKERFILE_DIR=kokoro/linux/64-bit
+export DOCKERHUB_ORGANIZATION=protobuftesting
+export DOCKERFILE_DIR=kokoro/linux/dockerfile/test/csharp
 export DOCKER_RUN_SCRIPT=kokoro/linux/pull_request_in_docker.sh
 export OUTPUT_DIR=testoutput
 export TEST_SET="csharp"
diff --git a/kokoro/linux/dockerfile/test/csharp/Dockerfile b/kokoro/linux/dockerfile/test/csharp/Dockerfile
new file mode 100644
index 0000000..2073057
--- /dev/null
+++ b/kokoro/linux/dockerfile/test/csharp/Dockerfile
@@ -0,0 +1,36 @@
+FROM debian:stretch
+
+# Install dependencies.  We start with the basic ones require to build protoc
+# and the C++ build
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  git \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  parallel \
+  time \
+  wget \
+  && apt-get clean
+
+# dotnet SDK prerequisites
+RUN apt-get update && apt-get install -y libunwind8 libicu57 && apt-get clean
+
+# Install dotnet SDK via install script
+RUN wget -q https://dot.net/v1/dotnet-install.sh && \
+    chmod u+x dotnet-install.sh && \
+    ./dotnet-install.sh --version 2.1.504 && \
+    ln -s /root/.dotnet/dotnet /usr/local/bin
+
+RUN wget -q www.nuget.org/NuGet.exe -O /usr/local/bin/nuget.exe
+
+ENV DOTNET_SKIP_FIRST_TIME_EXPERIENCE true
diff --git a/kokoro/release/csharp/windows/build_nuget.bat b/kokoro/release/csharp/windows/build_nuget.bat
index 5da1e13..fdb02b0 100644
--- a/kokoro/release/csharp/windows/build_nuget.bat
+++ b/kokoro/release/csharp/windows/build_nuget.bat
@@ -2,4 +2,9 @@
 cd /d %~dp0\..\..\..\..
 
 cd csharp
+
+@rem Install dotnet SDK
+powershell -File install_dotnet_sdk.ps1
+set PATH=%LOCALAPPDATA%\Microsoft\dotnet;%PATH%
+
 call build_packages.bat