Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tool for upgrading from v7 to v8 #291

Merged
merged 2 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions .github/workflows/publish-release.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
name: Pack and publish nugets
name: Pack and publish

on:
release:
types:
- published

jobs:
build-pack:
release-nugets:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -17,7 +18,6 @@ jobs:
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
5.0.x
6.0.x
- name: Install deps
run: |
Expand All @@ -33,4 +33,37 @@ jobs:
dotnet --version
- name: Publish
run: |
dotnet nuget push src/**/bin/Release/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}
dotnet nuget push src/**/bin/Release/*.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }}
release-upgrade-tool:
if: startsWith(github.ref, 'refs/tags/altinn-app-cli')
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./cli-tools/altinn-app-cli
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install dotnet6
uses: actions/setup-dotnet@v3
with:
dotnet-version: |
6.0.x
- name: Build bundles
run: |
make bundles
- name: Upload files to release
uses: softprops/action-gh-release@v1
with:
files: |
publish/archives/osx-x64.tar.gz
publish/archives/osx-arm64.tar.gz
publish/archives/linux-x64.tar.gz
publish/archives/linux-arm64.tar.gz
publish/archives/win-x64.zip
publish/archives/osx-x64.tar.gz.sha512
publish/archives/osx-arm64.tar.gz.sha512
publish/archives/linux-x64.tar.gz.sha512
publish/archives/linux-arm64.tar.gz.sha512
publish/archives/win-x64.zip.sha512

42 changes: 42 additions & 0 deletions cli-tools/altinn-app-cli/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Path: Makefile

build:
dotnet build

executable-osx-x64:
dotnet publish -c Release -o publish/osx-x64 -r osx-x64 --self-contained

executable-osx-arm64:
dotnet publish -c Release -o publish/osx-arm64 -r osx-arm64 --self-contained

executable-win-x64:
dotnet publish -c Release -o publish/win-x64 -r win-x64 --self-contained

executable-linux-x64:
dotnet publish -c Release -o publish/linux-x64 -r linux-x64 --self-contained

executable-linux-arm64:
dotnet publish -c Release -o publish/linux-arm64 -r linux-arm64 --self-contained

executables: executable-osx-x64 executable-osx-arm64 executable-win-x64 executable-linux-x64 executable-linux-arm64

archives:
mkdir -p publish/archives
tar -czvf publish/archives/osx-x64.tar.gz publish/osx-x64/altinn-app-cli
tar -czvf publish/archives/osx-arm64.tar.gz publish/osx-arm64/altinn-app-cli
tar -czvf publish/archives/linux-x64.tar.gz publish/linux-x64/altinn-app-cli
tar -czvf publish/archives/linux-arm64.tar.gz publish/linux-arm64/altinn-app-cli
zip -r publish/archives/win-x64.zip publish/win-x64/altinn-app-cli.exe

checksums:
sha512sum publish/archives/osx-x64.tar.gz > publish/archives/osx-x64.tar.gz.sha512
sha512sum publish/archives/osx-arm64.tar.gz > publish/archives/osx-arm64.tar.gz.sha512
sha512sum publish/archives/linux-x64.tar.gz > publish/archives/linux-x64.tar.gz.sha512
sha512sum publish/archives/linux-arm64.tar.gz > publish/archives/linux-arm64.tar.gz.sha512
sha512sum publish/archives/win-x64.zip > publish/archives/win-x64.zip.sha512

bundles: executables archives checksums

clean:
dotnet clean
rm -rf publish/
191 changes: 191 additions & 0 deletions cli-tools/altinn-app-cli/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
using System.CommandLine;
using System.Reflection;
using altinn_app_cli.v7Tov8.CodeRewriters;
using altinn_app_cli.v7Tov8.ProcessRewriter;
using altinn_app_cli.v7Tov8.ProjectChecks;
using altinn_app_cli.v7Tov8.ProjectRewriters;
using Microsoft.Build.Locator;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.MSBuild;

namespace altinn_app_upgrade_cli;

class Program
{
static async Task<int> Main(string[] args)
{
int returnCode = 0;
var projectFolderOption = new Option<string>(name: "--folder", description: "The project folder to read", getDefaultValue: () => "CurrentDirectory");
var projectFileOption = new Option<string>(name: "--project", description: "The project file to read relative to --folder", getDefaultValue: () => "App/App.csproj");
var processFileOption = new Option<string>(name: "--process", description: "The process file to read relative to --folder", getDefaultValue: () => "App/config/process/process.bpmn");
var targetVersionOption = new Option<string>(name: "--target-version", description: "The target version to upgrade to", getDefaultValue: () => "8.0.0-preview.9");
var skipCsprojUpgradeOption = new Option<bool>(name: "--skip-csproj-upgrade", description: "Skip csproj file upgrade", getDefaultValue: () => false);
var skipCodeUpgradeOption = new Option<bool>(name: "--skip-code-upgrade", description: "Skip code upgrade", getDefaultValue: () => false);
var skipProcessUpgradeOption = new Option<bool>(name: "--skip-process-upgrade", description: "Skip process file upgrade", getDefaultValue: () => false);
var rootCommand = new RootCommand("Command line interface for working with Altinn 3 Applications");
var upgradeCommand = new Command("upgrade", "Upgrade an app from v7 to v8")
{
projectFolderOption,
projectFileOption,
processFileOption,
targetVersionOption,
skipCsprojUpgradeOption,
skipCodeUpgradeOption,
skipProcessUpgradeOption,
};
rootCommand.AddCommand(upgradeCommand);
var versionCommand = new Command("version", "Print version of altinn-app-cli");
rootCommand.AddCommand(versionCommand);

upgradeCommand.SetHandler(async (projectFolder, projectFile, processFile, targetVersion, skipCodeUpgrade, skipProcessUpgrade, skipCsprojUpgrade) =>
{
if (projectFolder == "CurrentDirectory")
{
projectFolder = Directory.GetCurrentDirectory();
}

if (File.Exists(projectFolder))
{
Console.WriteLine($"Project folder {projectFolder} does not exist. Please supply location of project with --folder [path/to/project]");
returnCode = 1;
return;
}

FileAttributes attr = File.GetAttributes(projectFolder);
if ((attr & FileAttributes.Directory) != FileAttributes.Directory)
{
Console.WriteLine($"Project folder {projectFolder} is a file. Please supply location of project with --folder [path/to/project]");
returnCode = 1;
return;
}

if (!Path.IsPathRooted(projectFolder))
{
projectFile = Path.Combine(Directory.GetCurrentDirectory(), projectFolder, projectFile);
processFile = Path.Combine(Directory.GetCurrentDirectory(), projectFolder, processFile);
}
else
{
projectFile = Path.Combine(projectFolder, projectFile);
processFile = Path.Combine(projectFolder, processFile);
}

var projectChecks = new ProjectChecks(projectFile);
if (!projectChecks.SupportedSourceVersion())
{
Console.WriteLine($"Version(s) in project file {projectFile} is not supported. Please upgrade to version 7.0.0 or higher.");
returnCode = 2;
return;
}
if (!skipCsprojUpgrade)
{
returnCode = await UpgradeNugetVersions(projectFile, targetVersion);
}

if (!skipCodeUpgrade && returnCode == 0)
{
returnCode = await UpgradeCode(projectFile);
}

if (!skipProcessUpgrade && returnCode == 0)
{
returnCode = await UpgradeProcess(processFile);
}

if (returnCode == 0)
{
Console.WriteLine("Upgrade completed without errors. Please verify that the application is still working as expected.");
}
else
{
Console.WriteLine("Upgrade completed with errors. Please check for errors in the log above.");
}
},
projectFolderOption, projectFileOption, processFileOption, targetVersionOption, skipCodeUpgradeOption, skipProcessUpgradeOption, skipCsprojUpgradeOption);
versionCommand.SetHandler(() =>
{
var version = Assembly.GetEntryAssembly()?.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown";
Console.WriteLine($"altinn-app-cli v{version}");
});
await rootCommand.InvokeAsync(args);
return returnCode;
}

static async Task<int> UpgradeNugetVersions(string projectFile, string targetVersion)
{
if (!File.Exists(projectFile))
{
Console.WriteLine($"Project file {projectFile} does not exist. Please supply location of project with --project [path/to/project.csproj]");
return 1;
}

Console.WriteLine("Trying to upgrade nuget versions in project file");
var rewriter = new ProjectFileRewriter(projectFile, targetVersion);
await rewriter.Upgrade();
Console.WriteLine("Nuget versions upgraded");
return 0;
}

static async Task<int> UpgradeCode(string projectFile)
{
if (!File.Exists(projectFile))
{
Console.WriteLine($"Project file {projectFile} does not exist. Please supply location of project with --project [path/to/project.csproj]");
return 1;
}

Console.WriteLine("Trying to upgrade references and using in code");

MSBuildLocator.RegisterDefaults();
var workspace = MSBuildWorkspace.Create();
var project = await workspace.OpenProjectAsync(projectFile);
var comp = await project.GetCompilationAsync();
if (comp == null)
{
Console.WriteLine("Could not get compilation");
return 1;
}
foreach (var sourceTree in comp.SyntaxTrees)
{
SemanticModel sm = comp.GetSemanticModel(sourceTree);
TypesRewriter rewriter = new(sm);
SyntaxNode newSource = rewriter.Visit(await sourceTree.GetRootAsync());
if (newSource != await sourceTree.GetRootAsync())
{
await File.WriteAllTextAsync(sourceTree.FilePath, newSource.ToFullString());
}
UsingRewriter usingRewriter = new();
var newUsingSource = usingRewriter.Visit(newSource);
if (newUsingSource != newSource)
{
await File.WriteAllTextAsync(sourceTree.FilePath, newUsingSource.ToFullString());
}
}

Console.WriteLine("References and using upgraded");
return 0;
}

static async Task<int> UpgradeProcess(string processFile)
{
if (!File.Exists(processFile))
{
Console.WriteLine($"Process file {processFile} does not exist. Please supply location of project with --process [path/to/project.csproj]");
return 1;
}

Console.WriteLine("Trying to upgrade process file");
ProcessUpgrader parser = new(processFile);
parser.Upgrade();
await parser.Write();
var warnings = parser.GetWarnings();
foreach (var warning in warnings)
{
Console.WriteLine(warning);
}

Console.WriteLine(warnings.Any() ? "Process file upgraded with warnings. Review the warnings above and make sure that the process file is still valid." : "Process file upgraded");

return 0;
}
}
42 changes: 42 additions & 0 deletions cli-tools/altinn-app-cli/altinn-app-cli.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>altinn_app_cli</RootNamespace>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
<AssemblyName>altinn-app-cli</AssemblyName>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>false</PublishTrimmed>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Build.Locator" Version="1.4.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.6.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.6.0" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="MinVer" Version="4.3.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" PrivateAssets="All" />
</ItemGroup>
<PropertyGroup>
<RepoRoot>$([System.IO.Directory]::GetParent($(MSBuildThisFileDirectory)).Parent.FullName)</RepoRoot>
<MinVerDefaultPreReleasePhase>preview</MinVerDefaultPreReleasePhase>
<MinVerTagPrefix>altinn-app-cli</MinVerTagPrefix>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<LangVersion>10.0</LangVersion>
</PropertyGroup>

<Target Name="AssemblyVersionTarget" AfterTargets="MinVer" Condition="'$(MinVerVersion)'!=''">
<PropertyGroup>
<Version>$(MinVerMajor).$(MinVerMinor).$(MinVerPatch)</Version>
</PropertyGroup>
</Target>
</Project>
Loading
Loading