Update push-github-n-nuget-packages.yml #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish NuGet Package | |
| on: | |
| push: | |
| branches: [main] | |
| release: | |
| types: [published, prerelease] | |
| permissions: | |
| contents: write | |
| packages: write | |
| jobs: | |
| publish-nuget: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: 🧾 Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: 🛠️ Debug workflow start | |
| run: | | |
| echo "Workflow started for package ITSMAndSysAdminTools" | |
| echo "Event: ${{ github.event_name }}" | |
| echo "Repository: ${{ github.repository }}" | |
| echo "Commit: ${{ github.sha }}" | |
| echo "Listing repository contents:" | |
| ls -R | |
| echo "Checking for .nuspec file:" | |
| ls -l ITSMAndSysAdminTools.nuspec || echo "ITSMAndSysAdminTools.nuspec not found" | |
| echo "Checking for LICENSE file:" | |
| ls -l LICENSE || echo "LICENSE not found in root" | |
| echo "Checking for CHANGELOG.md:" | |
| ls -l CHANGELOG.md || echo "CHANGELOG.md not found in root" | |
| echo "Checking for package directories:" | |
| for dir in Core-ScriptLibrary BlueTeam-Tools SysAdmin-Tools ITSM-Templates-WKS ITSM-Templates-SVR; do | |
| ls -lR "$dir" || echo "Directory $dir not found" | |
| done | |
| echo "Checking .NET SDK version:" | |
| dotnet --version | |
| echo "Checking for mono and nuget availability:" | |
| which mono || echo "mono not found" | |
| which nuget || echo "nuget not found" | |
| - name: 📦 Install dependencies | |
| run: | | |
| echo "Installing mono-complete and xmlstarlet" | |
| sudo apt-get update | |
| sudo apt-get install -y mono-complete xmlstarlet | |
| echo "Checking mono version:" | |
| mono --version | |
| echo "Installing nuget.exe" | |
| wget -O nuget.exe https://dist.nuget.org/win-x86-commandline/v6.11.0/nuget.exe | |
| chmod +x nuget.exe | |
| sudo mv nuget.exe /usr/local/bin/nuget | |
| echo "Verifying nuget command:" | |
| mono /usr/local/bin/nuget help | head -n 1 | |
| - name: 📁 Prepare and stage files | |
| id: prepare | |
| run: | | |
| pkg="ITSMAndSysAdminTools" | |
| nuspec="ITSMAndSysAdminTools.nuspec" | |
| echo "Preparing package $pkg" | |
| if [ ! -f "$nuspec" ]; then | |
| echo "❌ Error: NuSpec file $nuspec missing in root, skipping package" | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| mkdir -p ReadmeCopies nupkg-out "tmp-$pkg" | |
| for dir in Core-ScriptLibrary BlueTeam-Tools SysAdmin-Tools ITSM-Templates-WKS ITSM-Templates-SVR; do | |
| if [ -d "$dir" ]; then | |
| echo "Copying package directory $dir to tmp-$pkg/$dir" | |
| cp -r "$dir/." "tmp-$pkg/$dir/" | |
| else | |
| echo "⚠️ Warning: Folder $dir missing" | |
| fi | |
| done | |
| cp "$nuspec" "tmp-$pkg/$nuspec" | |
| if [ -f "README.md" ]; then | |
| cp "README.md" "ReadmeCopies/$pkg-README.md" | |
| cp "ReadmeCopies/$pkg-README.md" "tmp-$pkg/$pkg-README.md" | |
| echo "Copied README.md for $pkg" | |
| else | |
| echo "⚠️ Warning: README.md not found in root" | |
| fi | |
| if [ -f "icon.png" ]; then | |
| cp "icon.png" "tmp-$pkg/icon.png" | |
| echo "Copied icon.png for $pkg" | |
| else | |
| echo "⚠️ Warning: icon.png not found in root" | |
| fi | |
| if [ -f "LICENSE" ]; then | |
| cp "LICENSE" "tmp-$pkg/LICENSE" | |
| echo "Copied LICENSE to tmp-$pkg" | |
| else | |
| echo "❌ Error: LICENSE file not found in root, skipping package" | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Listing tmp-$pkg contents:" | |
| ls -lR "tmp-$pkg" | |
| echo "Checking .nuspec file contents:" | |
| cat "$nuspec" | |
| echo "Validating .nuspec metadata:" | |
| xmlstarlet val "$nuspec" || { echo "❌ Error: Invalid XML in $nuspec"; echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0; } | |
| xmlstarlet sel -t -m "//metadata/id" -v . "$nuspec" > /dev/null || { echo "❌ Error: Missing id in $nuspec"; echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0; } | |
| xmlstarlet sel -t -m "//metadata/version" -v . "$nuspec" > /dev/null || { echo "❌ Error: Missing version in $nuspec"; echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0; } | |
| xmlstarlet sel -t -m "//metadata/authors" -v . "$nuspec" > /dev/null || { echo "❌ Error: Missing authors in $nuspec"; echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0; } | |
| xmlstarlet sel -t -m "//metadata/description" -v . "$nuspec" > /dev/null || { echo "❌ Error: Missing description in $nuspec"; echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0; } | |
| xmlstarlet sel -t -m "//metadata/license" -v . "$nuspec" > /dev/null || { echo "❌ Error: Missing license in $nuspec"; echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0; } | |
| xmlstarlet sel -t -m "//metadata/projectUrl" -v . "$nuspec" > /dev/null || { echo "❌ Error: Missing projectUrl in $nuspec"; echo "skip=true" >> "$GITHUB_OUTPUT"; exit 0; } | |
| echo "Validating .nuspec file paths:" | |
| invalid_paths=false | |
| grep '<file src="' "$nuspec" | while read -r line ; do | |
| src=$(echo "$line" | sed -E 's/.*src="([^"]+)".*/\1/') | |
| if [[ "$src" == */*/* ]]; then | |
| dir=$(echo "$src" | cut -d'/' -f1) | |
| if [ -d "tmp-$pkg/$dir" ]; then | |
| echo "Path $src exists in tmp-$pkg" | |
| else | |
| echo "❌ Error: Directory $dir for $src in $nuspec does not exist in tmp-$pkg" | |
| invalid_paths=true | |
| fi | |
| elif [ -f "tmp-$pkg/$src" ]; then | |
| echo "Path $src exists in tmp-$pkg" | |
| else | |
| echo "❌ Error: File $src in $nuspec does not exist in tmp-$pkg" | |
| invalid_paths=true | |
| fi | |
| done | |
| if [ "$invalid_paths" = "true" ]; then | |
| echo "❌ Error: Invalid paths found in $nuspec, skipping package" | |
| echo "skip=true" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "skip=false" >> "$GITHUB_OUTPUT" | |
| - name: 📖 Enhance .nuspec with rich metadata | |
| if: steps.prepare.outputs.skip != 'true' | |
| run: | | |
| pkg="ITSMAndSysAdminTools" | |
| nuspec="ITSMAndSysAdminTools.nuspec" | |
| version=$(xmlstarlet sel -t -m "//metadata/version" -v . "$nuspec" || echo "1.0.0") | |
| if [ -z "$version" ]; then | |
| echo "⚠️ Warning: Version not found in $nuspec, using default" | |
| version="1.0.0" | |
| fi | |
| echo "version=$version" >> "$GITHUB_OUTPUT" | |
| changelog=$(awk "/^## \\[$version\\]/,/^## \\[/" CHANGELOG.md | sed '1d;/^## \\[/d' || echo "No changelog found for version $version") | |
| changelog_sanitized=$(printf "%s" "$changelog" | sed ':a;N;$!ba;s/\n/\\n/g;s/"/\\"/g') | |
| echo "notes=$changelog_sanitized" >> "$GITHUB_OUTPUT" | |
| cp "tmp-$pkg/$nuspec" "tmp-$pkg/$nuspec.bak" | |
| xmlstarlet ed \ | |
| -u "//metadata/releaseNotes" -v "$changelog_sanitized" \ | |
| -s "//metadata[not(releaseNotes)]" -t elem -n "releaseNotes" -v "$changelog_sanitized" \ | |
| -u "//metadata/tags" -v "powershell itsm sysadmin security gpo automation enterprise activedirectory network wsus configuration" \ | |
| -s "//metadata[not(tags)]" -t elem -n "tags" -v "powershell itsm sysadmin security gpo automation enterprise activedirectory network wsus configuration" \ | |
| -s "//metadata[not(icon)]" -t elem -n "icon" -v "icon.png" \ | |
| -s "//metadata[not(repository)]" -t elem -n "repository" -v "" \ | |
| -s "//metadata/repository" -t attr -n "type" -v "git" \ | |
| -s "//metadata/repository" -t attr -n "url" -v "https://github.com/${{ github.repository }}" \ | |
| -s "//metadata/repository" -t attr -n "branch" -v "${{ github.ref_name }}" \ | |
| -s "//metadata/repository" -t attr -n "commit" -v "${{ github.sha }}" \ | |
| -s "//metadata[not(copyright)]" -t elem -n "copyright" -v "Copyright (c) 2025 Luiz Hamilton Roberto da Silva" \ | |
| -s "//metadata[not(owners)]" -t elem -n "owners" -v "Luiz Hamilton Roberto da Silva" \ | |
| -s "//metadata[not(requireLicenseAcceptance)]" -t elem -n "requireLicenseAcceptance" -v "false" \ | |
| "tmp-$pkg/$nuspec" > "tmp-$pkg/$nuspec.tmp" | |
| mv "tmp-$pkg/$nuspec.tmp" "tmp-$pkg/$nuspec" | |
| if [ -f "tmp-$pkg/$pkg-README.md" ]; then | |
| xmlstarlet ed -s "//files" -t elem -n "file" -v "" \ | |
| -s "//files/file[last()]" -t attr -n "src" -v "$pkg-README.md" \ | |
| -s "//files/file[last()]" -t attr -n "target" -v "content" \ | |
| "tmp-$pkg/$nuspec" > "tmp-$pkg/$nuspec.tmp" | |
| mv "tmp-$pkg/$nuspec.tmp" "tmp-$pkg/$nuspec" | |
| fi | |
| if [ -f "tmp-$pkg/icon.png" ]; then | |
| xmlstarlet ed -s "//files" -t elem -n "file" -v "" \ | |
| -s "//files/file[last()]" -t attr -n "src" -v "icon.png" \ | |
| -s "//files/file[last()]" -t attr -n "target" -v "images" \ | |
| "tmp-$pkg/$nuspec" > "tmp-$pkg/$nuspec.tmp" | |
| mv "tmp-$pkg/$nuspec.tmp" "tmp-$pkg/$nuspec" | |
| fi | |
| echo "Updated .nuspec with rich metadata:" | |
| cat "tmp-$pkg/$nuspec" | |
| - name: 📦 Pack NuGet package | |
| if: steps.prepare.outputs.skip != 'true' | |
| run: | | |
| pkg="ITSMAndSysAdminTools" | |
| nuspec="ITSMAndSysAdminTools.nuspec" | |
| if [ ! -d "tmp-$pkg" ]; then | |
| echo "❌ Error: Directory tmp-$pkg missing, skipping package" | |
| exit 0 | |
| fi | |
| cd "tmp-$pkg" | |
| mono /usr/local/bin/nuget pack "$nuspec" \ | |
| -OutputDirectory ../nupkg-out \ | |
| -Symbols -SymbolPackageFormat snupkg \ | |
| -NonInteractive \ | |
| || { echo "❌ Error: Failed to pack $nuspec"; exit 0; } | |
| - name: 🚀 Push to GitHub Packages | |
| if: steps.prepare.outputs.skip != 'true' && (github.event_name == 'push' || github.event_name == 'release') | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| for pkg_path in nupkg-out/*.nupkg nupkg-out/*.snupkg; do | |
| if [ -f "$pkg_path" ]; then | |
| echo "Pushing $pkg_path to GitHub Packages" | |
| mono /usr/local/bin/nuget push "$pkg_path" \ | |
| -Source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" \ | |
| -ApiKey "$GITHUB_TOKEN" \ | |
| -NonInteractive -SkipDuplicate | |
| fi | |
| done | |
| - name: 🚀 Push to NuGet.org | |
| if: steps.prepare.outputs.skip != 'true' && (github.event_name == 'push' || github.event_name == 'release') | |
| env: | |
| NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} | |
| run: | | |
| for pkg_path in nupkg-out/*.nupkg nupkg-out/*.snupkg; do | |
| if [ -f "$pkg_path" ]; then | |
| echo "Pushing $pkg_path to NuGet.org" | |
| mono /usr/local/bin/nuget push "$pkg_path" \ | |
| -Source "https://api.nuget.org/v3/index.json" \ | |
| -ApiKey "$NUGET_API_KEY" \ | |
| -NonInteractive -SkipDuplicate | |
| fi | |
| done | |
| - name: 🏷️ Create Git tag | |
| if: steps.prepare.outputs.skip != 'true' && (github.event_name == 'push' || github.event_name == 'release') | |
| run: | | |
| tag="ITSMAndSysAdminTools-v${{ steps.prepare.outputs.version }}" | |
| if git tag --list | grep -q "^$tag$"; then | |
| echo "Tag $tag already exists, skipping creation" | |
| else | |
| git config user.name "github-actions" | |
| git config user.email "github-actions@github.com" | |
| git tag "$tag" | |
| git push origin "$tag" | |
| fi | |
| - name: 🧹 Clean up | |
| if: always() | |
| run: | | |
| rm -rf "tmp-ITSMAndSysAdminTools" ReadmeCopies nupkg-out || true |