Skip to content

Commit ce6aec2

Browse files
committed
docs(blog): update SeedFolder posts with evolution, CI, and code samples
✨ Moved "Evolution and Updates" into the original 2020 post and removed the duplicate section to centralize historical context 📁 Modified: - _posts/2020-10-05-creating-a.net-core-global-tool.md - _posts/2025-08-20-evolving-seedfolder-with-github-copilot.md 🔧 Updated the follow-up post to reflect project evolution and to modernize examples. Changes include: - corrected code block languages (powershell, csharp, diff) - adjusted target frameworks and template lists - improved template-system code samples (enums, records, parsing) 🔁 Reworked CI example: added yaml schema, refined triggers and paths-ignore, upgraded actions, added env vars, integration tests, pack/publish steps, and conditional NuGet publishing for master 💡 Purpose: improve accuracy, readability, and usefulness of the blog posts for readers and contributors
1 parent cac0577 commit ce6aec2

File tree

3 files changed

+124
-69
lines changed

3 files changed

+124
-69
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@
6969
"Newtonsoft",
7070
"noindex",
7171
"nokogiri",
72+
"NOLOGO",
7273
"nuget",
7374
"nupkg",
7475
"omnisharp",
76+
"OPTOUT",
7577
"Permalinks",
7678
"picklist",
7779
"postbacks",
@@ -84,6 +86,7 @@
8486
"Rakefile",
8587
"rebranded",
8688
"Remmina",
89+
"rohith",
8790
"Roslynator",
8891
"rubygems",
8992
"s",

_posts/2020-10-05-creating-a.net-core-global-tool.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ tags:
99
- dotnetcore
1010

1111
---
12+
13+
**Evolution and Updates** 🔄
14+
15+
Since publishing this post, SeedFolder has evolved significantly! The tool now supports multiple project templates, cross-platform compatibility, and has been enhanced with the help of GitHub Copilot.
16+
17+
Read about the journey from a simple dotfile copier to a comprehensive project scaffolding tool in my follow-up post: [Evolving SeedFolder with GitHub Copilot - From Personal Tool to Multi-Template System](/2025/08/20/evolving-seedfolder-with-github-copilot.html).
18+
1219
**Overview**
1320

1421
I have now built my first .NET Core Global Tool!
@@ -181,12 +188,6 @@ jobs:
181188
PACKAGE_NAME: solrevdev.seedfolder
182189
```
183190
184-
**Evolution and Updates** 🔄
185-
186-
Since publishing this post, SeedFolder has evolved significantly! The tool now supports multiple project templates, cross-platform compatibility, and has been enhanced with the help of GitHub Copilot.
187-
188-
Read about the journey from a simple dotfile copier to a comprehensive project scaffolding tool in my follow-up post: [Evolving SeedFolder with GitHub Copilot - From Personal Tool to Multi-Template System](/2025/08/20/evolving-seedfolder-with-github-copilot.html).
189-
190191
**Find More** 🔍
191192
192193
Now that you have built and published a .NET Core Global Tool you may wish to find some others for inspiration.

_posts/2025-08-20-evolving-seedfolder-with-github-copilot.md

Lines changed: 114 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ tags:
1313
---
1414
**Overview**
1515

16-
It's been over 4 years since I first published my [.NET Core Global Tool](/2020/10/05/creating-a.net-core-global-tool.html) blog post about creating SeedFolder. What started as a simple tool to copy my personal dotfiles has evolved into something much more powerful and useful to the broader developer community.
16+
It's been over 4 years since I first published my [.NET Core Global Tool](/2020/10/05/creating-a.net-core-global-tool.html) blog post about creating SeedFolder.
17+
18+
What started as a simple tool to copy my personal dotfiles has evolved into something much more powerful and hopefully eventually will be useful to the broader developer community.
1719

1820
The original version was quite limited - it basically just copied my specific `.editorconfig`, `.gitignore`, and other dotfiles to new project folders. While this was useful for me, it wasn't particularly helpful to other developers who might have different preferences or work with different technology stacks.
1921

@@ -25,14 +27,13 @@ Over the years, I've made several significant improvements to SeedFolder, partic
2527

2628
One of the consistent maintenance tasks has been keeping the tool updated with each .NET LTS release. For example, [upgrading to .NET 7](https://github.com/solrevdev/seedfolder/pull/4) involved updating the target framework and ensuring compatibility:
2729

28-
```xml
30+
```diff
2931
<Project Sdk="Microsoft.NET.Sdk">
3032
<PropertyGroup>
3133
<OutputType>Exe</OutputType>
32-
<TargetFramework>net8.0</TargetFramework>
34+
- <TargetFramework>net6.0</TargetFramework>
3335
<!-- Multi-targeting for backward compatibility -->
34-
<TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
35-
36+
+ <TargetFrameworks>net8.0;net9.0</TargetFrameworks>
3637
<PackAsTool>true</PackAsTool>
3738
<ToolCommandName>seedfolder</ToolCommandName>
3839
<!-- ... other properties -->
@@ -58,7 +59,7 @@ For example, [Issue #9](https://github.com/solrevdev/seedfolder/issues/9) outlin
5859

5960
The biggest transformation was moving from a single set of dotfiles to a comprehensive template system. [Pull Request #10](https://github.com/solrevdev/seedfolder/pull/10) introduced support for six different project types:
6061

61-
```bash
62+
```powershell
6263
# Interactive mode - prompts for template selection
6364
seedfolder
6465
@@ -79,16 +80,16 @@ Each template now includes carefully curated files appropriate for that project
7980
- **dotnet**: .editorconfig, .gitignore for C#, omnisharp.json
8081
- **node**: package.json template, .nvmrc, npm-specific .gitignore
8182
- **python**: requirements.txt, .python-version, Python .gitignore
82-
- **ruby**: Gemfile template, .ruby-version, Ruby .gitignore
83+
- **ruby**: Gemfile template, .ruby-version, Ruby .gitignore
8384
- **markdown**: Basic structure for documentation projects
8485
- **universal**: Generic files useful across all project types
8586

8687
**Enhanced User Experience**
8788

8889
The tool is now much more user-friendly and customizable. Some key improvements include:
8990

90-
**Interactive Mode**:
91-
```bash
91+
**Interactive Mode**:
92+
```powershell
9293
$ seedfolder
9394
? Select a project template: (Use arrow keys)
9495
❯ dotnet - .NET applications with C# configuration
@@ -100,7 +101,7 @@ $ seedfolder
100101
```
101102

102103
**Better CLI Interface**:
103-
```bash
104+
```powershell
104105
# All the standard options you'd expect
105106
seedfolder --help
106107
seedfolder --version
@@ -115,38 +116,75 @@ seedfolder --template dotnet --output ./projects MyApi
115116
[Pull Request #16](https://github.com/solrevdev/seedfolder/pull/16) addressed CI workflow issues and simplified the build process:
116117

117118
```yaml
118-
# Simplified from complex matrix to reliable single job
119+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
120+
119121
name: CI
120-
on:
121-
push:
122-
branches: [ master ]
123-
pull_request:
124-
branches: [ master ]
125122

123+
on:
124+
push:
125+
branches:
126+
- master
127+
- release/*
128+
paths-ignore:
129+
- '**/*.md'
130+
- '**/*.gitignore'
131+
- '**/*.gitattributes'
132+
pull_request:
133+
branches:
134+
- master
135+
- release/*
136+
paths-ignore:
137+
- '**/*.md'
138+
- '**/*.gitignore'
139+
- '**/*.gitattributes'
126140
jobs:
127-
build:
128-
runs-on: ubuntu-latest
129-
steps:
130-
- uses: actions/checkout@v3
131-
132-
- name: Setup .NET
133-
uses: actions/setup-dotnet@v3
134-
with:
135-
dotnet-version: |
136-
6.0.x
137-
7.0.x
138-
8.0.x
139-
140-
- name: Build and Test
141-
run: |
142-
dotnet build --configuration Release
143-
dotnet test --configuration Release --no-build
144-
145-
- name: Pack and Publish
146-
if: github.ref == 'refs/heads/master'
147-
run: |
148-
dotnet pack --configuration Release --no-build
149-
dotnet nuget push "**/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }}
141+
build:
142+
if: github.event_name == 'push' && contains(toJson(github.event.commits), '***NO_CI***') == false && contains(toJson(github.event.commits), '[ci skip]') == false && contains(toJson(github.event.commits), '[skip ci]') == false
143+
runs-on: ubuntu-latest
144+
env:
145+
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
146+
DOTNET_CLI_TELEMETRY_OPTOUT: 1
147+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
148+
DOTNET_NOLOGO: true
149+
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
150+
DOTNET_ADD_GLOBAL_TOOLS_TO_PATH: false
151+
DOTNET_MULTILEVEL_LOOKUP: 0
152+
153+
steps:
154+
- name: checkout code
155+
uses: actions/checkout@v4
156+
157+
- name: setup .net core sdk
158+
uses: actions/setup-dotnet@v4
159+
with:
160+
dotnet-version: |
161+
8.0.x
162+
9.0.x
163+
164+
- name: dotnet build
165+
run: dotnet build solrevdev.seedfolder.sln --configuration Release
166+
167+
- name: run integration tests
168+
run: ./tests/integration-test.sh
169+
170+
- name: dotnet pack
171+
run: dotnet pack solrevdev.seedfolder.sln -c Release --no-build --include-source --include-symbols
172+
173+
- name: setup nuget
174+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
175+
uses: nuget/setup-nuget@v1
176+
with:
177+
nuget-version: latest
178+
179+
- name: Publish NuGet
180+
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
181+
uses: rohith/[email protected]
182+
with:
183+
PROJECT_FILE_PATH: src/solrevdev.seedfolder.csproj # Relative to repository root
184+
NUGET_KEY: ${{secrets.NUGET_API_KEY}} # nuget.org API key
185+
PACKAGE_NAME: solrevdev.seedfolder
186+
187+
150188
```
151189

152190
**The Power of AI-Assisted Development** 🚀
@@ -158,42 +196,55 @@ What I found particularly interesting about working with GitHub Copilot was how
158196
- **User Experience**: Proposed CLI interface improvements that made the tool much more pleasant to use
159197
- **Testing Strategies**: Suggested test cases and scenarios I hadn't considered
160198

161-
Here's an example of how Copilot helped implement the template selection logic:
199+
Here's an example of how Copilot helped implement the template system using enums and pattern matching:
162200

163201
```csharp
164-
public static class TemplateManager
202+
// Template metadata structure for future extensibility
203+
internal record TemplateFile(string ResourceName, string FileName, string Description = "");
204+
205+
// Enum for supported project types
206+
internal enum ProjectType
165207
{
166-
private static readonly Dictionary<string, TemplateInfo> Templates = new()
167-
{
168-
["dotnet"] = new("dotnet", ".NET applications with C# configuration",
169-
new[] { ".editorconfig", ".gitignore", "omnisharp.json" }),
170-
["node"] = new("node", "Node.js applications with npm setup",
171-
new[] { "package.json", ".nvmrc", ".gitignore" }),
172-
// ... other templates
173-
};
208+
Dotnet, Node, Python, Ruby, Markdown, Universal
209+
}
174210

175-
public static TemplateInfo GetTemplate(string name)
211+
private static bool TryParseProjectType(string input, out ProjectType projectType)
212+
{
213+
projectType = input switch
176214
{
177-
return Templates.TryGetValue(name.ToLowerInvariant(), out var template)
178-
? template
179-
: throw new ArgumentException($"Template '{name}' not found");
180-
}
215+
"dotnet" or "net" or "csharp" => ProjectType.Dotnet,
216+
"node" or "nodejs" or "javascript" or "js" => ProjectType.Node,
217+
"python" or "py" => ProjectType.Python,
218+
"ruby" or "rb" => ProjectType.Ruby,
219+
"markdown" or "md" or "docs" => ProjectType.Markdown,
220+
"universal" or "basic" or "minimal" => ProjectType.Universal,
221+
_ => ProjectType.Dotnet
222+
};
223+
224+
return input is "dotnet" or "net" or "csharp" or "node" or "nodejs"
225+
or "javascript" or "js" or "python" or "py" or "ruby" or "rb"
226+
or "markdown" or "md" or "docs" or "universal" or "basic" or "minimal";
227+
}
181228

182-
public static void ListTemplates()
229+
private static TemplateFile[] GetTemplateFiles(ProjectType projectType)
230+
{
231+
return projectType switch
183232
{
184-
foreach (var (key, template) in Templates)
185-
{
186-
Console.WriteLine($" {key,-12} - {template.Description}");
187-
}
188-
}
233+
ProjectType.Node => GetNodeTemplate(),
234+
ProjectType.Python => GetPythonTemplate(),
235+
ProjectType.Ruby => GetRubyTemplate(),
236+
ProjectType.Markdown => GetMarkdownTemplate(),
237+
ProjectType.Universal => GetUniversalTemplate(),
238+
_ => GetDotnetTemplate()
239+
};
189240
}
190241
```
191242

192243
**Next Steps: The Marketplace Vision** 🏪
193244

194245
The next major evolution is planned around [Issue #15](https://github.com/solrevdev/seedfolder/issues/15) - creating a template marketplace. This will allow the community to share and install custom templates:
195246

196-
```bash
247+
```powershell
197248
# Future marketplace commands
198249
seedfolder marketplace search angular
199250
seedfolder marketplace install solrevdev/vue-typescript
@@ -203,7 +254,7 @@ seedfolder marketplace update
203254

204255
The marketplace will be hosted as a separate GitHub repository at `solrevdev/seedfolder-marketplace` with this structure:
205256

206-
```
257+
```powershell
207258
solrevdev/seedfolder-marketplace/
208259
├── templates/
209260
│ ├── angular/
@@ -225,7 +276,7 @@ This will enable developers to:
225276

226277
The current version is available on NuGet and much more capable than the original:
227278

228-
```bash
279+
```powershell
229280
# Install the latest version
230281
dotnet tool install --global solrevdev.seedfolder
231282

0 commit comments

Comments
 (0)