Skip to content
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
88 changes: 88 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: "CI"

on:
push:
branches: [ develop, main ]

jobs:
build:
runs-on: windows-latest

env:
Solution: "src/CleanMyPosts.sln"
UnitTest_Project: "src/UnitTests/UnitTests.csproj"
IntegrationTest_Project: "src/IntegrationTests/IntegrationTests.csproj"
FORCE_COLOR: "true"
DOTNET_LOGGING__CONSOLE__COLORBEHAVIOR: Enabled

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x

- name: Install .NET Tools (local)
run: |
dotnet new tool-manifest
dotnet tool install dotnet-reportgenerator-globaltool
dotnet tool install dotnet-sonarscanner

- name: Restore
run: dotnet restore "${{ env.Solution }}"

- name: Build and Test with SonarQube
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
dotnet tool run dotnet-sonarscanner begin `
/k:"thorstenalpers_CleanMyPosts" `
/o:"thorstenalpers" `
/d:sonar.token="${{ secrets.SONAR_TOKEN }}" `
/d:sonar.host.url="https://sonarcloud.io" `
/d:sonar.sources="src" `
/d:sonar.tests="src/UnitTests;src/IntegrationTests" `
/d:sonar.test.inclusions="**/*Tests.cs" `
/d:sonar.coverageReportPaths="TestResults/Reports/SonarQube.xml"

dotnet build "${{ env.Solution }}" --configuration Release --no-restore

# Run Unit Tests
dotnet test "${{ env.UnitTest_Project }}" `
--collect:"XPlat Code Coverage" `
--results-directory TestResults/UnitTests `
--configuration Release `
--logger "console;verbosity=detailed" `
--filter "TestCategory!=Long-Running"

# Run Integration Tests
dotnet test "${{ env.IntegrationTest_Project }}" `
--collect:"XPlat Code Coverage" `
--results-directory TestResults/IntegrationTests `
--configuration Release `
--logger "console;verbosity=detailed"

# Generate coverage reports
dotnet tool run reportgenerator `
-reports:TestResults/**/coverage.cobertura.xml `
-targetdir:TestResults/Reports `
-reporttypes:"Html;lcov;SonarQube;Cobertura" `

dotnet tool run dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"

- name: Upload to Coveralls
uses: coverallsapp/github-action@v2
with:
path-to-lcov: TestResults/Reports/lcov.info
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}

- name: Upload Test Coverage Report
uses: actions/upload-artifact@v4
with:
name: test-coverage-report
path: TestResults/Reports
142 changes: 142 additions & 0 deletions .github/workflows/deploy-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
name: "Deploy Release"

on:
workflow_dispatch: # manual trigger

jobs:
build:
runs-on: windows-latest

env:
Solution: "src/CleanMyPosts.sln"
UI_Project: "src/UI/UI.csproj"
UnitTest_Project: "src/UnitTests/UnitTests.csproj"
IntegrationTest_Project: "src/IntegrationTests/IntegrationTests.csproj"
Installer_Script: "installer/Installer.iss"
FORCE_COLOR: "true"
DOTNET_LOGGING__CONSOLE__COLORBEHAVIOR: Enabled

steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Important to fetch full history for git tag and branches

- name: Install .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.x

- name: Restore
run: dotnet restore "${{ env.Solution }}"

- name: Build
run: dotnet build "${{ env.Solution }}" --configuration Release --no-restore

- name: Run Unit Tests
run: dotnet test "${{ env.UnitTest_Project }}" --configuration Release --logger "console;verbosity=detailed" --filter "TestCategory!=Long-Running"

- name: Run Integration Tests
run: dotnet test "${{ env.IntegrationTest_Project }}" --configuration Release --logger "console;verbosity=detailed"

- name: Extract Version
id: get_version
shell: pwsh
run: |
$content = Get-Content "${{ env.UI_Project }}"
if ($content -match '<Version>(.+)</Version>') {
$version = $matches[1]
echo "VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Append
} else {
throw "Version not found in project file"
}

- name: Publish Single EXE
run: |
dotnet publish "${{ env.UI_Project }}" -c Release -r win-x64 --self-contained true `
/p:PublishSingleFile=true `
/p:IncludeAllContentForSelfExtract=true `
/p:EnableCompressionInSingleFile=true `
-o artifacts/single-exe

- name: Install Inno Setup
run: choco install innosetup --yes

- name: Build Setup EXE
run: |
iscc "/DMyAppVersion=${{ env.VERSION }}" "/DMyAppExePath=artifacts\\single-exe\\*" "${{ env.Installer_Script }}"

- name: Copy Setup EXE to Artifacts
run: |
mkdir -p artifacts/setup
copy installer\Output\CleanMyPosts-Setup-${{ env.VERSION }}.exe artifacts\setup\

- name: Rename Standalone EXE for Release
run: |
Rename-Item "artifacts/single-exe/CleanMyPosts.exe" "artifacts/single-exe/CleanMyPosts-standalone.exe"

- name: Generate update.xml
shell: pwsh
run: |
$version = "${{ env.VERSION }}"
$repo = "${{ github.repository }}"
$baseUrl = "https://github.com/$repo/releases/download/v$version"
$installerUrl = "$baseUrl/CleanMyPosts-Setup-$version.exe"
$changelogUrl = "https://github.com/$repo/releases/tag/v$version"
$xmlContent = @"
<?xml version='1.0' encoding='utf-8'?>
<updates>
<application>
<name>CleanMyPosts</name>
<version>$version</version>
<url>$installerUrl</url>
<changelog>$changelogUrl</changelog>
</application>
</updates>
"@
$xmlContent | Set-Content -Path "artifacts/update.xml" -Encoding UTF8

- name: Configure Git Credentials
run: |
echo "https://${{ secrets.GH_APIKEY }}@github.com" > $env:USERPROFILE\.git-credentials
git config --global credential.helper store
git config --global user.name "github-actions"
git config --global user.email "actions@github.com"

- name: Push update.xml to update-feed branch
run: |
git fetch origin update-feed || echo "No update-feed branch yet"
if git show-ref --verify --quiet refs/heads/update-feed; then
git checkout update-feed
else
git checkout --orphan update-feed
git rm -rf .
fi

cp artifacts/update.xml update.xml
git add update.xml

if git diff --cached --quiet; then
echo "No changes in update.xml; skipping commit"
else
git commit -m "Update appcast for version ${{ env.VERSION }}"
git push origin update-feed --force
fi

- name: Create Git Tag
run: |
git tag -a "v${{ env.VERSION }}" -m "Release v${{ env.VERSION }}"
git push origin "v${{ env.VERSION }}"

- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
tag_name: "v${{ env.VERSION }}"
name: "CleanMyPosts ${{ env.VERSION }}"
body_path: ./release-notes/v${{ env.VERSION }}.md
files: |
artifacts/single-exe/CleanMyPosts-standalone.exe
artifacts/setup/CleanMyPosts-Setup-${{ env.VERSION }}.exe
artifacts/update.xml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
# CleanMyPosts
![Banner](./src/UI/Assets/banner.png)


[![Windows](https://img.shields.io/badge/platform-Windows-blue)](#)
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE.txt)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=thorstenalpers_CleanMyPosts&metric=alert_status)](https://sonarcloud.io/project/issues?issueStatuses=OPEN%2CCONFIRMED&id=thorstenalpers_CleanMyPosts)
[![CI Tests](https://github.com/thorstenalpers/CleanMyPosts/actions/workflows/ci.yml/badge.svg)](https://github.com/thorstenalpers/CleanMyPosts/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/thorstenalpers/CleanMyPosts/badge.svg?branch=develop)](https://coveralls.io/github/thorstenalpers/CleanMyPosts?branch=develop)
[![Star this repo](https://img.shields.io/github/stars/thorstenalpers/CleanMyPosts.svg?style=social&label=Star&maxAge=60)](https://github.com/thorstenalpers/CleanMyPosts)


> ⚠️ **Warning:** Development in progress – the application has not been released.

Expand All @@ -21,7 +30,7 @@
* bookmark bar, hideable via settings


# 🧹 CleanMyPosts
---

**CleanMyPosts** is a lightweight Windows desktop application that securely deletes all tweets from your X (formerly Twitter) account in bulk. Designed for privacy-focused users, social media managers, or anyone looking to start fresh.

Expand Down
29 changes: 9 additions & 20 deletions installer/Installer.iss
Original file line number Diff line number Diff line change
@@ -1,40 +1,32 @@
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "CleanMyPosts"
#define MyAppVersion "0.0.1"
#define MyAppPublisher "Thorsten Alpers"
#define MyAppURL "https://github.com/thorstenalpers/CleanMyPosts"
#define MyAppExeName "CleanMyPosts.exe"
#define MyIconPath "..\src\UI\Assets\logo.ico"
#define MyAppExePath "..\src\UI\bin\Release\net9.0-windows10.0.19041.0\win-x64\publish\*"

; dynamically set in github actions, ifndef use local values
#ifndef MyAppVersion
#define MyAppVersion "0.0.1"
#endif
#ifndef MyAppExePath
#define MyAppExePath "..\src\UI\bin\Release\net9.0-windows10.0.19041.0\win-x64\publish\*"
#endif

[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{AEE32610-58A5-4785-98B0-B651865B30D2}}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
UninstallDisplayIcon={app}\{#MyAppExeName}
; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run
; on anything but x64 and Windows 11 on Arm.
ArchitecturesAllowed=x64compatible
; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the
; install be done in "64-bit mode" on x64 or Windows 11 on Arm,
; meaning it should use the native 64-bit Program Files directory and
; the 64-bit view of the registry.
ArchitecturesInstallIn64BitMode=x64compatible
DisableProgramGroupPage=yes
; Uncomment the following line to run in non administrative install mode (install for current user only).
PrivilegesRequired=admin
; PrivilegesRequiredOverridesAllowed=no
OutputBaseFilename=CleanMyPosts_Setup_{#MyAppVersion}
OutputBaseFilename=CleanMyPosts-Setup-{#MyAppVersion}
SolidCompression=yes
WizardStyle=modern
SetupIconFile={#MyIconPath}
Expand All @@ -49,13 +41,10 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
Source: "{#MyAppExePath}"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "{#MyIconPath}"; DestDir: "{app}"; Flags: ignoreversion

; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\logo.ico"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\logo.ico"; Tasks: desktopicon


[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

3 changes: 3 additions & 0 deletions release-notes/v0.0.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### What's Changed

* First Release
17 changes: 16 additions & 1 deletion src/CleanMyPosts.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UI", "UI\UI.csproj", "{48A1
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{A65F1C77-11C1-DC4F-0A69-6EE789D29685}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{F7B3E70B-3487-8FDC-C91B-9CA0F0F66BE0}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{F7B3E70B-3487-8FDC-C91B-9CA0F0F66BE0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -19,6 +19,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationTests", "IntegrationTests\IntegrationTests.csproj", "{59FDAA84-6701-32D0-9E5C-CA30D0B3B987}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
ProjectSection(SolutionItems) = preProject
..\.github\workflows\ci.yml = ..\.github\workflows\ci.yml
..\.github\workflows\deploy-release.yml = ..\.github\workflows\deploy-release.yml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -37,10 +45,17 @@ Global
{F7B3E70B-3487-8FDC-C91B-9CA0F0F66BE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7B3E70B-3487-8FDC-C91B-9CA0F0F66BE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7B3E70B-3487-8FDC-C91B-9CA0F0F66BE0}.Release|Any CPU.Build.0 = Release|Any CPU
{59FDAA84-6701-32D0-9E5C-CA30D0B3B987}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59FDAA84-6701-32D0-9E5C-CA30D0B3B987}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59FDAA84-6701-32D0-9E5C-CA30D0B3B987}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59FDAA84-6701-32D0-9E5C-CA30D0B3B987}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C5A00240-64B9-4718-9682-317A36915078}
EndGlobalSection
Expand Down
33 changes: 33 additions & 0 deletions src/IntegrationTests/IntegrationTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0-windows10.0.19041.0</TargetFramework>
<IsPackable>false</IsPackable>
<AssetTargetFallback>uap10.0.18362</AssetTargetFallback>
<Platforms>x64;x86;AnyCPU</Platforms>
<RootNamespace>CleanMyPosts.IntegrationTests</RootNamespace>
<DefaultNamespace>CleanMyPosts.IntegrationTests</DefaultNamespace>
<AssemblyName>CleanMyPosts.IntegrationTests</AssemblyName>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.msbuild" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\UI\UI.csproj" />
</ItemGroup>

</Project>
Loading
Loading