Skip to content

Commit 0bcee4f

Browse files
committed
2 parents bd906d8 + b9b26d6 commit 0bcee4f

5 files changed

Lines changed: 129 additions & 55 deletions

File tree

.github/workflows/create-release.yml

Lines changed: 99 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ jobs:
1717
runs-on: ubuntu-latest
1818
permissions:
1919
contents: write
20-
id-token: write
20+
id-token: write
2121
steps:
2222
- name: Checkout repository
2323
uses: actions/checkout@v4
2424
with:
25-
fetch-depth: 0
25+
fetch-depth: 0
2626

2727
- name: Verify signed tag
2828
env:
29-
GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
29+
GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
3030
run: |
3131
echo "Verifying tag signature for v${{ inputs.version }}..."
3232
<<<<<<< Updated upstream
@@ -38,9 +38,7 @@ jobs:
3838
# Import GPG key if available
3939
>>>>>>> Stashed changes
4040
if [ -n "$GPG_PUBLIC_KEY" ]; then
41-
# Write the key to a file first to avoid shell interpretation issues
4241
echo "$GPG_PUBLIC_KEY" > /tmp/gpg_public_key.asc
43-
# Fix any potential line ending issues
4442
sed -i 's/\r$//' /tmp/gpg_public_key.asc
4543
<<<<<<< Updated upstream
4644
# Make sure the key file has proper GPG armor headers
@@ -60,8 +58,7 @@ jobs:
6058
gpg --batch --import /tmp/gpg_public_key.asc || echo "::warning::Failed to import GPG key, but continuing..."
6159
echo "GPG Public Key import attempted."
6260
echo "Available GPG keys:"
63-
gpg --list-keys # List keys for debugging
64-
# Clean up
61+
gpg --list-keys
6562
rm -f /tmp/gpg_public_key.asc
6663
=======
6764

@@ -84,7 +81,6 @@ jobs:
8481
# Check if tag exists in local repository
8582
if ! git tag -l "v${{ inputs.version }}" | grep -q "v${{ inputs.version }}"; then
8683
echo "Tag not found in local repository, attempting to fetch from remote..."
87-
# Fetch the specific tag without overwriting existing ones
8884
git fetch origin tag "v${{ inputs.version }}" --no-tags
8985
fi
9086

@@ -138,13 +134,31 @@ jobs:
138134
uses: actions/download-artifact@v4
139135
with:
140136
path: release-artifacts
141-
137+
138+
- name: Download SHA256 Hash Artifact
139+
uses: actions/download-artifact@v4
140+
with:
141+
name: sha256-hash
142+
path: ./
143+
144+
- name: Read SHA256 Hash
145+
id: read_hash
146+
shell: pwsh
147+
run: |
148+
$hashPath = "./sha256_hash.txt"
149+
if (Test-Path $hashPath) {
150+
$hash = Get-Content -Path $hashPath -Raw
151+
echo "sha256_hash=$hash" >> $env:GITHUB_OUTPUT
152+
echo "Read hash: $hash"
153+
} else {
154+
echo "::error::SHA256 hash file not found at $hashPath"
155+
exit 1
156+
}
157+
142158
- name: List downloaded artifacts
143159
run: |
144160
echo "All downloaded artifacts:"
145161
find release-artifacts -type f | sort
146-
147-
# Show specific information for the Windows installer
148162
WINDOWS_INSTALLER=$(find release-artifacts/windows-installer -name "*.exe" | head -1)
149163
if [ -n "$WINDOWS_INSTALLER" ]; then
150164
echo "Found Windows installer: $WINDOWS_INSTALLER"
@@ -153,7 +167,7 @@ jobs:
153167
echo "Warning: No Windows installer found!"
154168
fi
155169
156-
- name: Find Windows Installer
170+
- name: Find Windows Installer
157171
id: find_installer
158172
run: |
159173
INSTALLER_PATH=$(find release-artifacts -name "MPSS_Setup_*.exe" -o -name "*.exe" | grep -i "setup" | head -1)
@@ -168,27 +182,27 @@ jobs:
168182
find release-artifacts -name "*.exe" || echo "No .exe files found"
169183
exit 1
170184
fi
171-
- name: Install cosign
185+
186+
- name: Install cosign
172187
uses: sigstore/cosign-installer@v3.4.0
173188

174-
- name: Sign Windows Installer with Cosign
189+
- name: Sign Windows Installer with Cosign
175190
id: sign_installer
176191
run: |
177192
INSTALLER_PATH="${{ steps.find_installer.outputs.path }}"
178193
echo "Signing $INSTALLER_PATH..."
179194
cosign sign-blob --yes "$INSTALLER_PATH" --output-signature "${INSTALLER_PATH}.sig"
180195
echo "Signature created at ${INSTALLER_PATH}.sig"
181196
echo "signature_path=${INSTALLER_PATH}.sig" >> $GITHUB_OUTPUT
182-
183-
- name: Prepare verification information
197+
198+
- name: Prepare verification information
184199
run: |
185-
# Ensure verification-artifacts directory exists
186200
mkdir -p verification-info
187-
188-
# Copy verification artifacts to a directory
189201
cp -r release-artifacts/verification-artifacts/* verification-info/ || echo "No verification artifacts found"
190-
191-
# Create verification readme
202+
INSTALLER_PATH="${{ steps.find_installer.outputs.path }}"
203+
INSTALLER_FILENAME=$(basename "$INSTALLER_PATH")
204+
CERT_IDENTITY="https://github.com/${{ github.repository }}/.github/workflows/build.yml@refs/tags/v${{ inputs.version }}"
205+
CERT_ISSUER="https://token.actions.githubusercontent.com"
192206
cat > verification-info/README.md << EOF
193207
# Build Verification
194208
@@ -204,16 +218,36 @@ jobs:
204218
205219
## Signature Verification
206220
207-
The checksums are signed using [Sigstore/cosign](https://github.com/sigstore/cosign). You can verify the signature with:
221+
### Checksum Signature
208222
223+
The checksums file (\`SHA256SUMS.txt\`) is signed using [Sigstore/cosign](https://github.com/sigstore/cosign). You can verify its signature with:
224+
225+
\`\`\`bash
226+
cosign verify-blob \
227+
--certificate-identity "$CERT_IDENTITY" \
228+
--certificate-oidc-issuer "$CERT_ISSUER" \
229+
--signature SHA256SUMS.txt.sig \
230+
SHA256SUMS.txt
209231
\`\`\`
210-
cosign verify-blob --signature SHA256SUMS.txt.sig SHA256SUMS.txt
232+
233+
### Executable Signature
234+
235+
You can also verify the signature of the Windows executable file (\`$INSTALLER_FILENAME\`) directly:
236+
237+
\`\`\`bash
238+
cosign verify-blob \
239+
--certificate-identity "$CERT_IDENTITY" \
240+
--certificate-oidc-issuer "$CERT_ISSUER" \
241+
--signature "${INSTALLER_FILENAME}.sig" \
242+
"$INSTALLER_FILENAME"
211243
\`\`\`
212244
245+
These commands verify that the signature was created by the expected GitHub Actions workflow (`build.yml`) for this specific tag (`v${{ inputs.version }}`).
246+
213247
## Build Provenance
214248
215249
This build was created by GitHub Actions workflow run #${{ github.run_number }} (ID: ${{ github.run_id }}).
216-
250+
217251
View the build: https://github.com/kavinthangavel/Media-Player-Scrobbler-for-Simkl/actions/runs/${{ github.run_id }}
218252
EOF
219253
@@ -226,15 +260,14 @@ jobs:
226260
sudo apt update
227261
sudo apt install gh
228262
)
229-
230-
- name: Create Release with Provenance
263+
264+
- name: Create Release and Upload Initial Artifacts
231265
env:
232266
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
233267
TAG_VERIFIED: ${{ steps.verify_tag.outputs.tag_verified }}
234268
run: |
235269
VERSION="${{ inputs.version }}"
236-
INSTALLER_PATH="${{ steps.find_installer.outputs.path }}" # Use path from previous step
237-
270+
INSTALLER_PATH="${{ steps.find_installer.outputs.path }}"
238271
echo "Windows installer to upload: $INSTALLER_PATH"
239272
240273
<<<<<<< Updated upstream
@@ -261,14 +294,6 @@ jobs:
261294
gh release create "v$VERSION" \
262295
"$INSTALLER_PATH" \
263296
--title "Release $VERSION" \
264-
--notes "# MPSS Release $VERSION
265-
266-
## Verification
267-
268-
This release was built using GitHub Actions workflow run #${{ github.run_number }} (ID: ${{ github.run_id }}).
269-
You can verify the authenticity of this build by checking the SHA256 checksums and signature files included with this release.
270-
271-
View the build: https://github.com/kavinthangavel/Media-Player-Scrobbler-for-Simkl/actions/runs/${{ github.run_id }}" \
272297
--generate-notes \
273298
--verify-tag \
274299
=======
@@ -292,15 +317,13 @@ EOF
292317
--discussion-category "Releases"
293318
echo "Release created and Windows installer attached."
294319
fi
295-
296-
# Upload verification info (checksums, checksum sig)
320+
297321
echo "Uploading verification artifacts from verification-info/ ..."
298322
find verification-info -type f | while read file; do
299323
echo "Uploading $file..."
300324
gh release upload "v$VERSION" "$file" --clobber
301325
done
302-
303-
# Upload the installer signature
326+
304327
INSTALLER_SIG_PATH="${{ steps.sign_installer.outputs.signature_path }}"
305328
if [ -f "$INSTALLER_SIG_PATH" ]; then
306329
echo "Uploading installer signature: $INSTALLER_SIG_PATH"
@@ -309,8 +332,41 @@ EOF
309332
echo "::warning:: Installer signature file not found at $INSTALLER_SIG_PATH"
310333
fi
311334
echo "Verification artifacts uploaded."
312-
313-
- name: Delete all workflow artifacts after release
335+
336+
- name: Update Release Body with SHA256 Hash
337+
env:
338+
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
339+
VERSION: ${{ inputs.version }}
340+
SHA256_HASH: ${{ steps.read_hash.outputs.sha256_hash }}
341+
shell: bash
342+
run: |
343+
echo "Fetching current release body for v${VERSION}..."
344+
EXISTING_BODY=$(gh release view "v$VERSION" --json body --jq .body)
345+
346+
if [ -z "$SHA256_HASH" ]; then
347+
echo "::error::SHA256_HASH is empty. Cannot update release body."
348+
exit 1
349+
fi
350+
351+
INSTALLER_BASENAME="MPSS_Setup_${VERSION}.exe"
352+
353+
SHA_TABLE=$(cat <<EOF
354+
355+
| File | SHA256 |
356+
| ------------------------ | ---------------------------------------- |
357+
| ${INSTALLER_BASENAME} | ${SHA256_HASH} |
358+
EOF
359+
)
360+
361+
echo "Appending SHA256 table to release body..."
362+
printf -v NEW_BODY "%s\n%s" "$EXISTING_BODY" "$SHA_TABLE"
363+
364+
echo "Updating release v${VERSION}..."
365+
gh release edit "v$VERSION" --notes "$NEW_BODY"
366+
echo "Release body updated successfully."
367+
368+
- name: Delete build artifacts
314369
uses: geekyeggo/delete-artifact@v5
315370
with:
316-
name: '*'
371+
name: |
372+
python-package

.github/workflows/windows-build.yml

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ jobs:
5555
SIMKL_CLIENT_SECRET: ${{ secrets.SIMKL_CLIENT_SECRET }}
5656
shell: bash
5757
run: |
58-
# Check if secrets are available
5958
if [ -z "$SIMKL_CLIENT_ID" ]; then
6059
echo "::error::SIMKL_CLIENT_ID secret is not set."
6160
exit 1
@@ -65,7 +64,6 @@ jobs:
6564
exit 1
6665
fi
6766
68-
# Inject Client ID and Secret
6967
sed -i "s|SIMKL_CLIENT_ID_PLACEHOLDER|${SIMKL_CLIENT_ID}|g" simkl_mps/credentials.py
7068
sed -i "s|SIMKL_CLIENT_SECRET_PLACEHOLDER|${SIMKL_CLIENT_SECRET}|g" simkl_mps/credentials.py
7169
@@ -77,13 +75,10 @@ jobs:
7775
run: |
7876
pip install pyinstaller
7977
80-
# Patch is now included directly in simkl-mps.spec
8178
python -m PyInstaller --clean simkl-mps.spec
8279
83-
# Make sure the destination directory exists before copying
8480
New-Item -Path "dist\simkl-mps" -ItemType Directory -Force
8581
86-
# Copy build_info.json to the PyInstaller dist directory
8782
Copy-Item -Path "build-info\build_info.json" -Destination "dist\simkl-mps\" -Force
8883
8984
- name: Test PyInstaller build
@@ -94,16 +89,13 @@ jobs:
9489
- name: Build Installer with Inno Setup
9590
run: |
9691
$version = "${{ inputs.version }}"
97-
# Replace version in setup.iss
9892
(Get-Content setup.iss) -replace '#define MyAppVersion "[^"]*"', "#define MyAppVersion `"$version`"" | Set-Content setup_temp.iss
9993
100-
# Find the end of the [Files] section and properly add the build_info.json entry
10194
$fileContent = Get-Content setup_temp.iss -Raw
10295
$filesPattern = "(\[Files\].*?)(^\[)"
10396
$newContent = $fileContent -replace $filesPattern, "`$1`r`nSource: `"build-info\build_info.json`"; DestDir: `"{app}`"; Flags: ignoreversion`r`n`r`n`$2" -replace '(?smi)'
10497
Set-Content -Path setup_temp.iss -Value $newContent
10598
106-
# Compile the setup
10799
& 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe' /Q setup_temp.iss
108100
109101
- name: Rename and move installer
@@ -112,6 +104,32 @@ jobs:
112104
mkdir -p artifacts
113105
Move-Item dist\installer\MPSS_Setup_$version.exe artifacts\MPSS_Setup_$version.exe
114106
107+
- name: Calculate SHA256 for EXE
108+
id: hash_exe
109+
shell: pwsh
110+
run: |
111+
$filePath = "artifacts/MPSS_Setup_${{ inputs.version }}.exe"
112+
$hash = (Get-FileHash -Path $filePath -Algorithm SHA256).Hash
113+
echo "sha256_hash=$hash" >> $env:GITHUB_OUTPUT
114+
echo "Calculated hash: $hash for file: $filePath"
115+
116+
- name: Create SHA256 Hash File
117+
id: create_hash_file
118+
shell: pwsh
119+
run: |
120+
$hashValue = "${{ steps.hash_exe.outputs.sha256_hash }}"
121+
$tempFilePath = Join-Path $env:RUNNER_TEMP "sha256_hash.txt"
122+
Set-Content -Path $tempFilePath -Value $hashValue
123+
echo "hash_file_path=$tempFilePath" >> $env:GITHUB_OUTPUT
124+
echo "Created hash file at $tempFilePath"
125+
126+
- name: Upload SHA256 Hash Artifact
127+
uses: actions/upload-artifact@v4
128+
with:
129+
name: sha256-hash # Name of the artifact
130+
path: ${{ steps.create_hash_file.outputs.hash_file_path }} # Path from previous step
131+
retention-days: 1 # Keep artifact for 1 day
132+
115133
- name: Upload Windows artifacts
116134
uses: actions/upload-artifact@v4
117135
with:

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "simkl-mps"
3-
version = "2.0.3"
3+
version = "2.0.4"
44
description = "Automatic Media Scrobbler for Simkl"
55
authors = [
66
"kavinthangavel <kavinthangavel.dev@gmail.com>",
@@ -61,7 +61,7 @@ markers = "sys_platform == 'linux' and python_version >= '3.9' and python_versio
6161
[tool.poetry.urls]
6262
"Linux System Dependencies" = "https://github.com/kavinthangavel/media-player-scrobbler-for-simkl/wiki/Installation#linux-installation"
6363
"Bug Reports" = "https://github.com/kavinthangavel/media-player-scrobbler-for-simkl/issues"
64-
"Documentation" = "https://github.com/kavinthangavel/media-player-scrobbler-for-simkl/wiki"
64+
Documentation = "https://github.com/kavinthangavel/media-player-scrobbler-for-simkl/wiki"
6565

6666
[tool.poetry.group.dev.dependencies]
6767
pytest = ">=6.2.5"

setup.iss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#define MyAppURL "https://github.com/kavinthangavel/Media-Player-Scrobbler-for-Simkl"
55
#define MyAppExeName "MPSS"
66
#define MyAppTrayName "MPS for Simkl"
7-
#define MyAppVersion "2.0.3"
7+
#define MyAppVersion "2.0.4"
88
#define MyAppDescription "Automatically track and scrobble media you watch to SIMKL"
99
#define MyAppCopyright "Copyright (C) 2025 kavinthangavel"
1010
#define MyAppUpdateURL "https://github.com/kavinthangavel/Media-Player-Scrobbler-for-Simkl/releases"

simkl_mps/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Media Player Scrobbler for SIMKL package.
33
"""
44

5-
__version__ = "2.0.3"
5+
__version__ = "2.0.4"
66
__author__ = "kavinthangavel"
77

88
# Apply compatibility patches first, before any other imports

0 commit comments

Comments
 (0)