From 07c700c772e0a456782c679450697091deeca400 Mon Sep 17 00:00:00 2001 From: Rishabh Chawla Date: Tue, 15 Jul 2025 00:01:19 -0700 Subject: [PATCH 1/2] feat: Windows Signing --- .github/workflows/publish.yml | 119 +++++++++++++++++++++++++++++++++- README.md | 3 + package-lock.json | 4 +- package.json | 2 +- release/app/package-lock.json | 4 +- release/app/package.json | 2 +- 6 files changed, 126 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 017ad6a..127f6f5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,6 +7,7 @@ on: push: branches: - main + - windowsSigning jobs: build-and-publish: @@ -49,11 +50,125 @@ jobs: npm run postinstall npm run build - - name: Publish Windows release + - name: Get package version if: matrix.platform == 'win' + id: get-version + shell: bash + run: | + VERSION=$(node -p "require('./package.json').version") + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "artifact-name=Cobolt-Setup-$VERSION.exe" >> $GITHUB_OUTPUT + + - name: Check if release already exists + if: matrix.platform == 'win' + id: check-release + shell: bash + run: | + RELEASE_EXISTS=$(gh release view "v${{ steps.get-version.outputs.version }}" --json assets,draft --jq 'if .draft == false then .assets | map(select(.name == "${{ steps.get-version.outputs.artifact-name }}")) | length else 0 end' 2>/dev/null || echo "0") + echo "release-exists=$RELEASE_EXISTS" >> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Windows executable (no publish) + if: matrix.platform == 'win' + run: npm exec electron-builder -- --win --publish=never + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: upload-unsigned-artifact + id: upload-unsigned-artifact + if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' + uses: actions/upload-artifact@v4 + with: + name: cobolt-unsigned-installer + retention-days: 1 + path: | + release/build/Cobolt-Setup-${{ steps.get-version.outputs.version }}.exe + + - name: Start background approval process + if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' + run: | + # Start background process to approve signing requests + powershell -Command " + Start-Job -ScriptBlock { + Start-Sleep -Seconds 15 # Wait for signing request to be submitted + + `$headers = @{ + 'Authorization' = 'Bearer ${{secrets.SIGNPATH_API_TOKEN}}' + 'Content-Type' = 'application/json' + } + + for (`$i = 0; `$i -lt 60; `$i++) { + try { + `$requests = Invoke-RestMethod -Uri 'https://app.signpath.io/API/v1/3fe5dc9d-e6f6-4c25-83e5-70c5844441b9/SigningRequests?status=WaitingForApproval' -Headers `$headers -Method GET + + if (`$requests -and `$requests.Count -gt 0) { + foreach (`$request in `$requests) { + Write-Host 'Auto-approving signing request:' `$request.signingRequestId + + `$approvalBody = @{ + action = 'approve' + note = 'Auto-approved by GitHub Actions bot' + } | ConvertTo-Json + + Invoke-RestMethod -Uri \"https://app.signpath.io/API/v1/3fe5dc9d-e6f6-4c25-83e5-70c5844441b9/SigningRequests/`$(`$request.signingRequestId)/Approval\" -Headers `$headers -Method POST -Body `$approvalBody + Write-Host 'Approval successful' + } + break + } + } catch { + Write-Host 'Approval check failed, retrying...' + } + + Start-Sleep -Seconds 10 + } + } + " & + + - name: Sign artifact + if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' + uses: signpath/github-action-submit-signing-request@v1.1 + with: + api-token: ${{secrets.SIGNPATH_API_TOKEN}} + organization-id: 3fe5dc9d-e6f6-4c25-83e5-70c5844441b9 + project-slug: cobolt + signing-policy-slug: release-signing + github-artifact-id: ${{steps.upload-unsigned-artifact.outputs.artifact-id}} + wait-for-completion: true + output-artifact-directory: signed-artifacts + timeout-minutes: 15 + + - name: Update latest.yml with signed artifact details + if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' + shell: bash + run: | + # Get the size of the signed executable + SIGNED_SIZE=$(stat -c%s "signed-artifacts/${{ steps.get-version.outputs.artifact-name }}") + + # Update latest.yml to point to signed artifacts + if [ -f "release/build/latest.yml" ]; then + # Update the file reference and size in latest.yml + sed -i "s|size: [0-9]*|size: $SIGNED_SIZE|g" release/build/latest.yml + + # Copy updated latest.yml to signed-artifacts directory + cp release/build/latest.yml signed-artifacts/ + fi + + - name: Publish Windows release with signed executable + if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: npm exec electron-builder -- --publish --win + shell: bash + run: | + # Check if draft release already exists + if gh release view "${{ steps.get-version.outputs.version }}" --json draft --jq '.draft' 2>/dev/null | grep -q true; then + echo "Draft release exists, uploading to existing release" + gh release upload "${{ steps.get-version.outputs.version }}" signed-artifacts/${{ steps.get-version.outputs.artifact-name }} --clobber + gh release upload "${{ steps.get-version.outputs.version }}" signed-artifacts/latest.yml --clobber + else + echo "No draft release exists, creating new release" + gh release create "${{ steps.get-version.outputs.version }}" signed-artifacts/${{ steps.get-version.outputs.artifact-name }} signed-artifacts/latest.yml --title "${{ steps.get-version.outputs.version }}" --notes "Release ${{ steps.get-version.outputs.version }}" --draft + fi - name: Publish macOS release if: matrix.platform == 'mac' diff --git a/README.md b/README.md index 7e646b2..1b7f7ae 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,9 @@ Install-Module -Name Microsoft.WinGet.Client -Repository PSGallery -Confirm:$fal You can confirm winget is present using powershell with `winget -v` +Code signing policy: +* Free code signing on Windows provided by [SignPath.io](https://signpath.io), certificate by [SignPath Foundation](https://signpath.org) (thank you for your support!). + ## How to? ### How to change the model? diff --git a/package-lock.json b/package-lock.json index 2144ca6..df944d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cobolt", - "version": "0.0.6", + "version": "0.0.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cobolt", - "version": "0.0.6", + "version": "0.0.7", "hasInstallScript": true, "dependencies": { "@electron/notarize": "^3.0.0", diff --git a/package.json b/package.json index 10b4f24..6b3cfa9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cobolt", - "version": "0.0.6", + "version": "0.0.7", "description": "Your personal AI companion", "keywords": [], "repository": { diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 3800bbd..2fcc18d 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "cobolt", - "version": "0.0.6", + "version": "0.0.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cobolt", - "version": "0.0.6", + "version": "0.0.7", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/release/app/package.json b/release/app/package.json index 44b753e..fc35198 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "cobolt", - "version": "0.0.6", + "version": "0.0.7", "description": "Cobolt", "license": "MIT", "author": { From 597d3029e286ddf973a43ce1c8115e9d5884a2e6 Mon Sep 17 00:00:00 2001 From: Rishabh Chawla Date: Sat, 9 Aug 2025 00:20:44 -0700 Subject: [PATCH 2/2] gpt5 trying to fix --- .github/actions/windows-signing/action.yml | 216 +++++++++++++++++++++ .github/workflows/publish.yml | 117 +---------- package-lock.json | 4 +- package.json | 2 +- release/app/package-lock.json | 4 +- release/app/package.json | 2 +- 6 files changed, 228 insertions(+), 117 deletions(-) create mode 100644 .github/actions/windows-signing/action.yml diff --git a/.github/actions/windows-signing/action.yml b/.github/actions/windows-signing/action.yml new file mode 100644 index 0000000..2e87cec --- /dev/null +++ b/.github/actions/windows-signing/action.yml @@ -0,0 +1,216 @@ +name: Windows Signing and Publish +description: Sign Windows installer via SignPath and publish release +inputs: + signpath_api_token: + description: SignPath API token + required: true + signpath_sign_token: + description: SignPath Sign token + required: true +runs: + using: composite + steps: + - name: Get package version + id: get-version + shell: bash + run: | + VERSION=$(node -p "require('./package.json').version") + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "artifact-name=Cobolt-Setup-$VERSION.exe" >> "$GITHUB_OUTPUT" + + - name: Check if release already exists + id: check-release + shell: pwsh + env: + GH_TOKEN: ${{ env.GH_TOKEN }} + run: | + $TAG = '${{ steps.get-version.outputs.version }}' + $VTAG = "v$TAG" + $ARTIFACT = '${{ steps.get-version.outputs.artifact-name }}' + + try { + $json = gh release view $VTAG --json assets,isDraft 2>$null + $ghExit = $LASTEXITCODE + + $releaseExists = 0 + if (($ghExit -eq 0) -and ($json)) { + $info = $json | ConvertFrom-Json + $isDraft = $info.isDraft + $assets = @($info.assets) + $assetNames = if ($assets) { ($assets | ForEach-Object name) -join ', ' } else { '' } + + Write-Host "Debug: isDraft=$isDraft" + Write-Host "Debug: assets.count=$($assets.Count)" + + if ($info -and ($isDraft -eq $false)) { + $matches = $assets | Where-Object { $_.name -eq $ARTIFACT } + $releaseExists = @($matches).Count + } + } else { + Write-Host "Debug: gh did not return release info; setting releaseExists=0" + $releaseExists = 0 + } + } catch { + Write-Host "Debug: Exception in check-release: $($_.Exception.Message)" + $releaseExists = 0 + } + + "release-exists=$releaseExists" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8 + + - name: upload-unsigned-artifact + id: upload-unsigned-artifact + if: steps.check-release.outputs.release-exists == '0' + uses: actions/upload-artifact@v4 + with: + name: cobolt-unsigned-installer + retention-days: 1 + path: | + release/build/Cobolt-Setup-${{ steps.get-version.outputs.version }}.exe + + - name: Sign artifact (submit only) + if: steps.check-release.outputs.release-exists == '0' + id: signpath-submit + uses: signpath/github-action-submit-signing-request@v1.1 + with: + api-token: ${{ inputs.signpath_api_token }} + organization-id: 3fe5dc9d-e6f6-4c25-83e5-70c5844441b9 + project-slug: cobolt + signing-policy-slug: release-signing + github-artifact-id: ${{ steps.upload-unsigned-artifact.outputs.artifact-id }} + wait-for-completion: false + + - name: Wait 15 seconds before approval + if: steps.check-release.outputs.release-exists == '0' + shell: pwsh + run: Start-Sleep -Seconds 15 + + - name: Approve only this SignPath request + if: steps.check-release.outputs.release-exists == '0' + shell: pwsh + env: + SIGNPATH_SIGN_TOKEN: ${{ inputs.signpath_sign_token }} + run: | + $orgId = '3fe5dc9d-e6f6-4c25-83e5-70c5844441b9' + $id = '${{ steps.signpath-submit.outputs.signing-request-id }}' + + if (-not $id) { + Write-Error "Could not determine signing request id from action outputs." + exit 1 + } + + $headers = @{ + Authorization = "Bearer $env:SIGNPATH_SIGN_TOKEN" + 'Content-Type' = 'application/json' + } + $bodyJson = @{ action = 'approve'; note = "Auto-approved by GitHub Actions ($env:GITHUB_RUN_ID)" } | ConvertTo-Json + + $uri = "https://app.signpath.io/API/v1/$orgId/SigningRequests/$id/Approve" + Write-Host "Approving signing request $id at $uri" + + Invoke-RestMethod -Uri $uri -Headers $headers -Method POST -Body $bodyJson -ErrorAction Stop + Write-Host "Approval submitted for $id via Invoke-RestMethod" + + - name: Download signed artifact (poll until available) + if: steps.check-release.outputs.release-exists == '0' + shell: pwsh + env: + SIGNPATH_SIGN_TOKEN: ${{ inputs.signpath_sign_token }} + run: | + $orgId = '3fe5dc9d-e6f6-4c25-83e5-70c5844441b9' + $id = '${{ steps.signpath-submit.outputs.signing-request-id }}' + + if (-not $id) { + Write-Error "Could not determine signing request id from action outputs." + exit 1 + } + + $downloadUri = "https://app.signpath.io/API/v1/$orgId/SigningRequests/$id/SignedArtifact" + $outDir = "signed-artifacts" + New-Item -ItemType Directory -Path $outDir -Force | Out-Null + $outFile = Join-Path $outDir "${{ steps.get-version.outputs.artifact-name }}" + + $headers = @{ + Authorization = "Bearer $env:SIGNPATH_SIGN_TOKEN" + Accept = "application/octet-stream" + } + + $maxAttempts = 30 + $delaySec = 30 + + for ($i = 1; $i -le $maxAttempts; $i++) { + Write-Host "[$i/$maxAttempts] Attempting download: $downloadUri" + try { + Invoke-WebRequest -Uri $downloadUri -Headers $headers -OutFile $outFile -ErrorAction Stop + if ((Get-Item $outFile).Length -gt 0) { + Write-Host "Downloaded signed artifact to $outFile" + break + } + } + catch { + $status = try { $_.Exception.Response.StatusCode.value__ } catch { $null } + Write-Host "Not ready yet (HTTP $status). Waiting $delaySec sec..." + } + + if ($i -lt $maxAttempts) { + Start-Sleep -Seconds $delaySec + } + } + + if (-not (Test-Path $outFile) -or (Get-Item $outFile).Length -eq 0) { + throw "Failed to download signed artifact after $($maxAttempts * $delaySec) seconds" + } + + - name: Update latest.yml with signed artifact details + if: steps.check-release.outputs.release-exists == '0' + shell: pwsh + run: | + $signed = "signed-artifacts/${{ steps.get-version.outputs.artifact-name }}" + if ((Test-Path "release/build/latest.yml") -and (Test-Path $signed)) { + $size = (Get-Item $signed).Length + $bytes = [System.IO.File]::ReadAllBytes($signed) + $sha = [System.Security.Cryptography.SHA512]::Create() + $hashBytes = $sha.ComputeHash($bytes) + $sha512b64 = [Convert]::ToBase64String($hashBytes) + + $yml = Get-Content -Raw "release/build/latest.yml" + $yml = $yml -replace '(?m)^size:\s*\d+', "size: $size" + $yml = $yml -replace '(?m)^sha512:\s*.*', "sha512: $sha512b64" + Set-Content -Path "release/build/latest.yml" -Value $yml -Encoding UTF8 + + Copy-Item "release/build/latest.yml" "signed-artifacts/latest.yml" -Force + } + + - name: Publish Windows release with signed executable + if: steps.check-release.outputs.release-exists == '0' + shell: bash + env: + GH_TOKEN: ${{ env.GH_TOKEN }} + run: | + TAG="${{ steps.get-version.outputs.version }}" + VTAG="v$TAG" + + EXISTING_DRAFT_TAG=$(gh release list --limit 100 --json tagName,isDraft,name \ + --jq "map(select(.isDraft == true and .name == \"$TAG\")) | (.[0].tagName // empty)" || true) + + TARGET_TAG="" + if [ -n "$EXISTING_DRAFT_TAG" ]; then + TARGET_TAG="$EXISTING_DRAFT_TAG" + echo "Using existing draft release tagged $TARGET_TAG (title $TAG)" + elif gh release view "$VTAG" --json draft --jq '.draft' 2>/dev/null | grep -q true; then + TARGET_TAG="$VTAG" + echo "Using existing draft $TARGET_TAG" + else + echo "No draft release found; creating $VTAG (title $TAG)" + ARGS=( "$VTAG" "signed-artifacts/${{ steps.get-version.outputs.artifact-name }}" ) + if [ -f "signed-artifacts/latest.yml" ]; then + ARGS+=( "signed-artifacts/latest.yml" ) + fi + gh release create "${ARGS[@]}" --title "$TAG" --notes "Release $TAG" --draft + TARGET_TAG="$VTAG" + fi + + echo "Uploading assets to $TARGET_TAG" + gh release upload "$TARGET_TAG" "signed-artifacts/${{ steps.get-version.outputs.artifact-name }}" --clobber + if [ -f "signed-artifacts/latest.yml" ]; then + gh release upload "$TARGET_TAG" "signed-artifacts/latest.yml" --clobber + fi \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 127f6f5..39a94c2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -50,125 +50,20 @@ jobs: npm run postinstall npm run build - - name: Get package version + - name: Build Windows executable if: matrix.platform == 'win' - id: get-version - shell: bash - run: | - VERSION=$(node -p "require('./package.json').version") - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "artifact-name=Cobolt-Setup-$VERSION.exe" >> $GITHUB_OUTPUT - - - name: Check if release already exists - if: matrix.platform == 'win' - id: check-release - shell: bash - run: | - RELEASE_EXISTS=$(gh release view "v${{ steps.get-version.outputs.version }}" --json assets,draft --jq 'if .draft == false then .assets | map(select(.name == "${{ steps.get-version.outputs.artifact-name }}")) | length else 0 end' 2>/dev/null || echo "0") - echo "release-exists=$RELEASE_EXISTS" >> $GITHUB_OUTPUT + run: npm exec electron-builder -- --win --publish=never env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Build Windows executable (no publish) + - name: Windows sign and publish if: matrix.platform == 'win' - run: npm exec electron-builder -- --win --publish=never + uses: ./.github/actions/windows-signing env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: upload-unsigned-artifact - id: upload-unsigned-artifact - if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' - uses: actions/upload-artifact@v4 - with: - name: cobolt-unsigned-installer - retention-days: 1 - path: | - release/build/Cobolt-Setup-${{ steps.get-version.outputs.version }}.exe - - - name: Start background approval process - if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' - run: | - # Start background process to approve signing requests - powershell -Command " - Start-Job -ScriptBlock { - Start-Sleep -Seconds 15 # Wait for signing request to be submitted - - `$headers = @{ - 'Authorization' = 'Bearer ${{secrets.SIGNPATH_API_TOKEN}}' - 'Content-Type' = 'application/json' - } - - for (`$i = 0; `$i -lt 60; `$i++) { - try { - `$requests = Invoke-RestMethod -Uri 'https://app.signpath.io/API/v1/3fe5dc9d-e6f6-4c25-83e5-70c5844441b9/SigningRequests?status=WaitingForApproval' -Headers `$headers -Method GET - - if (`$requests -and `$requests.Count -gt 0) { - foreach (`$request in `$requests) { - Write-Host 'Auto-approving signing request:' `$request.signingRequestId - - `$approvalBody = @{ - action = 'approve' - note = 'Auto-approved by GitHub Actions bot' - } | ConvertTo-Json - - Invoke-RestMethod -Uri \"https://app.signpath.io/API/v1/3fe5dc9d-e6f6-4c25-83e5-70c5844441b9/SigningRequests/`$(`$request.signingRequestId)/Approval\" -Headers `$headers -Method POST -Body `$approvalBody - Write-Host 'Approval successful' - } - break - } - } catch { - Write-Host 'Approval check failed, retrying...' - } - - Start-Sleep -Seconds 10 - } - } - " & - - - name: Sign artifact - if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' - uses: signpath/github-action-submit-signing-request@v1.1 with: - api-token: ${{secrets.SIGNPATH_API_TOKEN}} - organization-id: 3fe5dc9d-e6f6-4c25-83e5-70c5844441b9 - project-slug: cobolt - signing-policy-slug: release-signing - github-artifact-id: ${{steps.upload-unsigned-artifact.outputs.artifact-id}} - wait-for-completion: true - output-artifact-directory: signed-artifacts - timeout-minutes: 15 - - - name: Update latest.yml with signed artifact details - if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' - shell: bash - run: | - # Get the size of the signed executable - SIGNED_SIZE=$(stat -c%s "signed-artifacts/${{ steps.get-version.outputs.artifact-name }}") - - # Update latest.yml to point to signed artifacts - if [ -f "release/build/latest.yml" ]; then - # Update the file reference and size in latest.yml - sed -i "s|size: [0-9]*|size: $SIGNED_SIZE|g" release/build/latest.yml - - # Copy updated latest.yml to signed-artifacts directory - cp release/build/latest.yml signed-artifacts/ - fi - - - name: Publish Windows release with signed executable - if: matrix.platform == 'win' && steps.check-release.outputs.release-exists == '0' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - shell: bash - run: | - # Check if draft release already exists - if gh release view "${{ steps.get-version.outputs.version }}" --json draft --jq '.draft' 2>/dev/null | grep -q true; then - echo "Draft release exists, uploading to existing release" - gh release upload "${{ steps.get-version.outputs.version }}" signed-artifacts/${{ steps.get-version.outputs.artifact-name }} --clobber - gh release upload "${{ steps.get-version.outputs.version }}" signed-artifacts/latest.yml --clobber - else - echo "No draft release exists, creating new release" - gh release create "${{ steps.get-version.outputs.version }}" signed-artifacts/${{ steps.get-version.outputs.artifact-name }} signed-artifacts/latest.yml --title "${{ steps.get-version.outputs.version }}" --notes "Release ${{ steps.get-version.outputs.version }}" --draft - fi + signpath_api_token: ${{ secrets.SIGNPATH_API_TOKEN }} + signpath_sign_token: ${{ secrets.SIGNPATH_SIGN_TOKEN }} - name: Publish macOS release if: matrix.platform == 'mac' diff --git a/package-lock.json b/package-lock.json index df944d7..2144ca6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cobolt", - "version": "0.0.7", + "version": "0.0.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cobolt", - "version": "0.0.7", + "version": "0.0.6", "hasInstallScript": true, "dependencies": { "@electron/notarize": "^3.0.0", diff --git a/package.json b/package.json index 6b3cfa9..10b4f24 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cobolt", - "version": "0.0.7", + "version": "0.0.6", "description": "Your personal AI companion", "keywords": [], "repository": { diff --git a/release/app/package-lock.json b/release/app/package-lock.json index 2fcc18d..3800bbd 100644 --- a/release/app/package-lock.json +++ b/release/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "cobolt", - "version": "0.0.7", + "version": "0.0.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cobolt", - "version": "0.0.7", + "version": "0.0.6", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/release/app/package.json b/release/app/package.json index fc35198..44b753e 100644 --- a/release/app/package.json +++ b/release/app/package.json @@ -1,6 +1,6 @@ { "name": "cobolt", - "version": "0.0.7", + "version": "0.0.6", "description": "Cobolt", "license": "MIT", "author": {