Skip to content

Commit

Permalink
Merge pull request #10 from tableau/lsz/v1.0.2
Browse files Browse the repository at this point in the history
v1.0.2 Release
  • Loading branch information
lszinv authored Nov 20, 2024
2 parents 7f24283 + 4c73f98 commit 0b64cd2
Show file tree
Hide file tree
Showing 105 changed files with 4,664 additions and 1,276 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Generate and Deploy DocFX Documentation

on:
push:
branches:
- main

jobs:
build-and-deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'

- name: Install DocFX
run: dotnet tool install -g docfx

- name: Add .dotnet/tools to PATH
run: echo "::add-path::${HOME}/.dotnet/tools"

- name: Build DocFX site
working-directory: ./docs
run: docfx

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/_site
publish_branch: gh-pages
keep_files: false
52 changes: 46 additions & 6 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ jobs:
- name: Build
run: dotnet build --configuration Release --no-restore

- name: Install ReportGenerator
run: dotnet tool install -g dotnet-reportgenerator-globaltool

- name: Test
run: dotnet test --no-build --configuration Release --verbosity normal
run: |
dotnet test --configuration Release tests/Tableau.Migration.App.Core.Tests/ /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=../../CoreCoverage.xml
dotnet test --configuration Release tests/Tableau.Migration.App.GUI.Tests /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=../../GUICoverage.xml
env:
TABLEAU_CLOUD_URL: ${{ secrets.TABLEAU_CLOUD_URL }}
TABLEAU_CLOUD_SITE: ${{ secrets.TABLEAU_CLOUD_SITE }}
Expand All @@ -36,9 +41,44 @@ jobs:
TABLEAU_SERVER_TOKEN_NAME: ${{ secrets.TABLEAU_SERVER_TOKEN_NAME }}
TABLEAU_SERVER_TOKEN: ${{ secrets.TABLEAU_SERVER_TOKEN }}

- name: Run dotnet format
run: dotnet format --verbosity diagnostic
- name: Generate coverage report
env:
PATH: $PATH:/home/runner/.dotnet/tools # Adds dotnet tools to PATH
run: reportgenerator -reports:"./*Coverage.xml" -targetdir:./coverage-report -reporttypes:"Html;TextSummary"

- name: Comment coverage summary on PR
uses: actions/github-script@v6
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs');
const summary = fs.readFileSync('./coverage-report/Summary.txt', 'utf8');
// Split the summary by lines and get the first 18
const topSummary = summary.split('\n').slice(0, 18).join('\n');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Code Coverage Summary\n\`\`\`\n${topSummary}\n\`\`\``
});
# Skipping for now due to line ending mismatches
# - name: Run dotnet format
# id: format
# run: |
# dotnet format --verbosity diagnostic > format.log
# grep -q 'Formatted code file' format.log || exit 0
# exit 1

- name: Check format results
if: failure()
run: echo "Formatting issues found. Please run 'dotnet format' locally and fix the issues."
# - name: Check format results
# if: failure()
# uses: actions/github-script@v6
# with:
# github-token: ${{ secrets.GITHUB_TOKEN }}
# script: |
# github.rest.issues.createComment({
# issue_number: context.issue.number,
# owner: context.repo.owner,
# repo: context.repo.repo,
# body: "Formatting issues were found and fixed. Please run 'dotnet format' locally to ensure your code is properly formatted."
# })
6 changes: 1 addition & 5 deletions BUILD.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Tableau ESMB Migration App
# Tableau Migration App
Tableau express migration application to migrate data sources from Tableau Server to Tableau Cloud.
Requirements doc can be found [here](https://docs.google.com/document/d/1DXrYdTbS5aGcZeicNVAdD1tvGRwtH1Yj/edit#heading=h.gjdgxs).

Expand All @@ -12,10 +12,6 @@ Requirements doc can be found [here](https://docs.google.com/document/d/1DXrYdTb
* Tableau.Migration.App.GUI - Gui implementation using Avalonia framework.

# Building
## From Container
The dockerfile is defined in the `Dockerfile` from the project root.
```
docker build .
```
## From Source Root
```
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/gui.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ Currently we have the following defined service interfaces:
The top level view used to hold all visible elements is located in the [MainWindow](/api/Tableau.Migration.App.GUI.Views.MainWindow.html) view.

## View Models
All ViewModels are named based on their appropriate View name. i.e. the [MainWindow](/api/Tableau.Migration.App.GUI.Views.MainWindow.html) view has an associatedv [MainWindowViewModel](api/Tableau.Migration.App.GUI.ViewModels.MainWindowViewModel.html).
All ViewModels are named based on their appropriate View name. i.e. the [MainWindow](/api/Tableau.Migration.App.GUI.Views.MainWindow.html) view has an associatedv [MainWindowViewModel](/api/Tableau.Migration.App.GUI.ViewModels.MainWindowViewModel.html)


There exist 2 abstract classes defined in the ViewModel folder:
- [**ViewModelBase**](/api/Tableau.Migration.App.GUI.ViewModels.ViewModelBase.html) - The base class of a ViewModel.
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
4 changes: 4 additions & 0 deletions docs/toc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- name: Docs
href: docs/
- name: API
href: api/
4 changes: 4 additions & 0 deletions scripts/gen_report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/bash
dotnet test tests/Tableau.Migration.App.Core.Tests/ /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=../../CoreCoverage.xml
dotnet test tests/Tableau.Migration.App.GUI.Tests /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:CoverletOutput=../../GUICoverage.xml
reportgenerator -reports:"./*Coverage.xml" -targetdir:./coverage-report -reporttypes:"Html;TextSummary"
2 changes: 2 additions & 0 deletions src/Tableau.Migration.App.Core/Entities/AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// limitations under the License.
// </copyright>

namespace Tableau.Migration.App.Core.Entities;

/// <summary>
/// App settings to be loaded.
/// </summary>
Expand Down
36 changes: 34 additions & 2 deletions src/Tableau.Migration.App.Core/Entities/DetailedMigrationResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="DetailedMigrationResult.cs" company="Salesforce, Inc.">
// <copyright file="DetailedMigrationResult.cs" company="Salesforce, Inc.">
// Copyright (c) 2024, Salesforce, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2
//
Expand Down Expand Up @@ -26,4 +26,36 @@ namespace Tableau.Migration.App.Core.Entities;
/// </summary>
public record struct DetailedMigrationResult(
ITableauMigrationService.MigrationStatus status,
IReadOnlyList<Exception> errors);
IReadOnlyList<Exception> errors);

/// <summary>
/// Builder to build a <see cref="DetailedMigrationResult" />.
/// </summary>
public static class DetailedMigrationResultBuilder
{
/// <summary>
/// Build a Detailed Migration Result.
/// </summary>
/// <param name="status">The Tableau Migration SDK Status.</param>
/// <param name="errors">The errors from migration.</param>
/// <returns>The <see cref="DetailedMigrationResult" />.</returns>
public static DetailedMigrationResult Build(
MigrationCompletionStatus status, IReadOnlyList<Exception> errors)
{
ITableauMigrationService.MigrationStatus newStatus;
switch (status)
{
case MigrationCompletionStatus.Completed:
newStatus = ITableauMigrationService.MigrationStatus.SUCCESS;
break;
case MigrationCompletionStatus.Canceled:
newStatus = ITableauMigrationService.MigrationStatus.CANCELED;
break;
default: // ITableauMigrationService.MigrationStatus.FAILURE
newStatus = ITableauMigrationService.MigrationStatus.FAILURE;
break;
}

return new DetailedMigrationResult(newStatus, errors);
}
}
31 changes: 29 additions & 2 deletions src/Tableau.Migration.App.Core/Entities/MigrationActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,48 @@ namespace Tableau.Migration.App.Core.Entities;
/// </summary>
public class MigrationActions
{
private static List<string> actionsCache = new List<string>();

/// <summary>
/// Gets the list of actions available from the Tableau Migration SDK and the order in which they are migrated.
/// </summary>
public static List<string> Actions
{
get
{
var result = ServerToCloudMigrationPipeline
if (actionsCache.Count > 0)
{
return actionsCache;
}

actionsCache = ServerToCloudMigrationPipeline
.ContentTypes
.Select(
contentType => GetActionTypeName(contentType.ContentType)).ToList();
return result;
actionsCache.Insert(0, "Setup");

return actionsCache;
}
}

/// <summary>
/// Get the index of a migration action.
/// </summary>
/// <param name="action">The migration action name.</param>
/// <returns>The migration index for the provided action.</returns>
public static int GetActionIndex(string action)
{
for (int i = 0; i < Actions.Count; i++)
{
if (action == Actions[i])
{
return i;
}
}

return -1;
}

/// <summary>
/// Returns the action type names from the SDK.
/// </summary>
Expand Down
67 changes: 67 additions & 0 deletions src/Tableau.Migration.App.Core/Entities/MigrationTimerEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// <copyright file="MigrationTimerEvent.cs" company="Salesforce, Inc.">
// Copyright (c) 2024, Salesforce, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2
//
// Licensed under the Apache License, Version 2.0 (the "License")
// You may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

namespace Tableau.Migration.App.Core.Entities;
using System;

/// <summary>
/// Possible value types for Migration Timer Events.
/// </summary>
public enum MigrationTimerEventType
{
/// <summary>
/// Event fired when Migration has started.
/// </summary>
MigrationStarted,

/// <summary>
/// Event fired when Migration has either completed or failed.
/// </summary>
Migrationfinished,

/// <summary>
/// Event fired when a Migration Action has completed.
/// </summary>
MigrationActionCompleted,
}

/// <summary>
/// Migration Time events to be triggered.
/// </summary>
public class MigrationTimerEvent : EventArgs
{
private DateTime migrationStartTime;
private Dictionary<string, DateTime> actionStartTimes;
private Dictionary<string, DateTime> actionStopTimes;

/// <summary>
/// Initializes a new instance of the <see cref="MigrationTimerEvent" /> class.
/// </summary>
/// <param name="eventType">The event type.</param>
public MigrationTimerEvent(MigrationTimerEventType eventType)
{
this.EventType = eventType;
this.migrationStartTime = DateTime.Now;
this.actionStartTimes = new Dictionary<string, DateTime>();
this.actionStopTimes = new Dictionary<string, DateTime>();
}

/// <summary>
/// Gets the Migration event type.
/// </summary>
public MigrationTimerEventType EventType { get; }
}
9 changes: 1 addition & 8 deletions src/Tableau.Migration.App.Core/Entities/ProgressEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,14 @@ public class ProgressEventArgs : EventArgs
/// <summary>
/// Initializes a new instance of the <see cref="ProgressEventArgs" /> class.
/// </summary>
/// <param name="action">The action.</param>
/// <param name="message">The message.</param>
public ProgressEventArgs(string action, string message)
public ProgressEventArgs(string message)
{
this.Message = message;
this.Action = action;
}

/// <summary>
/// Gets something.
/// </summary>
public string Message { get; }

/// <summary>
/// Gets something.
/// </summary>
public string Action { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class EmailDomainMapping :
ITableauCloudUsernameMapping
{
private readonly string domain;
private ILogger<EmailDomainMapping>? logger;

/// <summary>
/// Initializes a new instance of the <see cref="EmailDomainMapping"/> class.
Expand All @@ -44,10 +45,11 @@ public class EmailDomainMapping :
public EmailDomainMapping(
IOptions<EmailDomainMappingOptions> options,
ISharedResourcesLocalizer localizer,
ILogger<EmailDomainMapping> logger)
ILogger<EmailDomainMapping>? logger)
: base(localizer, logger)
{
this.domain = options.Value.EmailDomain;
this.logger = logger;
}

/// <summary>
Expand All @@ -71,6 +73,12 @@ public EmailDomainMapping(
return userMappingContext.MapTo(domain.Append(userMappingContext.ContentItem.Name)).ToTask();
}

if (string.IsNullOrEmpty(this.domain))
{
this.logger?.LogInformation("No domain mapping provided and no email found.");
return userMappingContext.ToTask();
}

// Takes the existing username and appends the domain to build the email
var email = $"{userMappingContext.ContentItem.Name}@{this.domain}";

Expand Down
Loading

0 comments on commit 0b64cd2

Please sign in to comment.