diff --git a/.github/workflows/build-with-firmwware.yml b/.github/workflows/build-with-firmwware.yml new file mode 100644 index 00000000000..3e7d58faa12 --- /dev/null +++ b/.github/workflows/build-with-firmwware.yml @@ -0,0 +1,220 @@ +name: "Build for Firmware" +run-name: "Build ${{ inputs.DEPLOY_TARGET }} by @${{ github.ACTOR }}" + +on: + workflow_dispatch: + inputs: + version: + description: "Enter version to build or left empty for current version" + required: false + type: string + release: + types: [unpublished] + push: + paths: + - .github/workflows/build-with-firmware.yml + +permissions: + contents: write + packages: write + +jobs: + build-and-upload: + # runs-on: [self-hosted, linux] + runs-on: ubuntu-latest + concurrency: + group: firmware-build-${{ vars.FIRMWARE_VERSION }}-${{ vars.RELEASE_VERSION }} + cancel-in-progress: false + env: + REPO_SELF: ${{ vars.REPO_SELF }} + IGNORED_PATH: "applications_user/subbrute" + RELATIVE_PATH: "applications/external/subbrute" + CURRENT_VERSION: ${{ vars.RELEASE_VERSION }} + strategy: + fail-fast: false + matrix: + firmware: [unlshd, official] + include: + - firmware: unlshd + url: ${{ vars.REPO_UNLEASHED }} + version: ${{ vars.FIRMWARE_VERSION }} + src-included: 1 + - firmware: official + url: ${{ vars.REPO_OFFICIAL }} + version: "official" + exclude: + - os: official + steps: + - name: Set version + env: + INPUT_VERSION: ${{ inputs.version }} + CURRENT_VERSION: ${{ env.CURRENT_VERSION }} + shell: pwsh + run: | + $ReleaseVersion = ([string]::IsNullOrWhitespace($env:INPUT_VERSION) ? $env:CURRENT_VERSION : $env:INPUT_VERSION) + Write-Output ('RELEASE_VERSION={0}' -f $ReleaseVersion) >> $env:GITHUB_ENV + + - name: Copy Repo Files + uses: actions/checkout@v3 + with: + repository: "${{ matrix.url }}" + clean: "true" + submodules: "true" + ref: "dev" + + - name: Copy Repo Files + if: ${{ matrix.src-included == 0 }} + uses: actions/checkout@v3 + with: + repository: "${{ vars.REPO_SELF }}" + clean: "true" + submodules: "true" + path: "${{ env.IGNORED_PATH }}" + + - name: Print vars about state or repo if Unleashed + if: ${{ matrix.src-included == 1 }} + shell: pwsh + run: | + git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1 + git submodule set-branch --branch master '${{ env.RELATIVE_PATH }}' + git submodule sync '${{ env.RELATIVE_PATH }}' + cd '${{ env.RELATIVE_PATH }}' + if ( '${{ env.CURRENT_VERSION }}' -ne '${{ env.RELEASE_VERSION }}' ) { + Write-Output '::warning title=Different version::Current version is ${{ env.CURRENT_VERSION }} but we trying to build ${{ env.RELEASE_VERSION }}' + git checkout tags/v${{ env.RELEASE_VERSION }} -b tmp-build + + if ( $LASTEXITCODE -ne 0 ) { + Write-Error '::error title=Cannot checkout to this version::Error during execution checkout to this tag ${{ env.RELEASE_VERSION }}' + exit 1 + } + } + + $Output = (git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1) + + if ( $LASTEXITCODE -ne 0 ) { + Write-Error '::error title=Invalid checkout::Invalid checkout' + exit 1 + } + Write-Output ('::notice title=Git output::{0}' -f $Output) + + - name: Print vars about state or repo if Official + if: ${{ matrix.src-included == 0 }} + shell: pwsh + run: | + git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1 + cd '${{ env.IGNORED_PATH }}' + + if ( '${{ env.CURRENT_VERSION }}' -ne '${{ env.RELEASE_VERSION }}' ) { + Write-Output '::warning title=Different version::Current version is ${{ env.CURRENT_VERSION }} but we trying to build ${{ env.RELEASE_VERSION }}' + git checkout tags/v${{ env.RELEASE_VERSION }} -b tmp-build + + if ( $LASTEXITCODE -ne 0 ) { + Write-Error '::error title=Cannot checkout to this version::Error during execution checkout to this tag ${{ env.RELEASE_VERSION }}' + exit 1 + } + } else { + $Output = (git log --pretty=format:'%s by %C(yellow)%an%Creset (%ad)%n %n%b' --date=local --abbrev-commit --max-count=1) + + if ( $LASTEXITCODE -ne 0 ) { + Write-Error '::error title=Invalid checkout::Invalid checkout' + exit 1 + } + Write-Output ('::notice title=Git output::{0}' -f $Output) + } + + # - name: Restore FBT + # id: cache-restore + # if: ${{ success() }} + # uses: actions/cache/restore@v3 + # with: + # path: | + # build/** + # debug/** + # # An explicit key for restoring and saving the cache + # key: 'fbt=${{ env.FIRMWARE_VERSION }}' + # + - name: Build Firmware + shell: bash + if: ${{ success() }} + env: + FBT_NO_SYNC: 0 + DIST_SUFFIX: ${{ matrix.version }} + WORKFLOW_BRANCH_OR_TAG: release-cfw + run: | + ./fbt COMPACT=1 DEBUG=0 fap_dist + + # - name: Save FBT + # id: cache-save + # if: ${{ success() }} + # uses: actions/cache/save@v3 + # with: + # path: | + # build/** + # debug/** + # # An explicit key for restoring and saving the cache + # key: ${{ steps.cache-restore.outputs.cache-primary-key }} + + - name: Create assets + if: ${{ success() }} + shell: pwsh + env: + ZIP_NAME: "SubGHz_Bruteforcer_${{ env.RELEASE_VERSION }}_${{ matrix.firmware }}.zip" + TGZ_NAME: "SubGHz_Bruteforcer_${{ env.RELEASE_VERSION }}_${{ matrix.firmware }}.tgz" + run: | + function Format-Bytes { + param( + [int]$number + ) + $sizes = 'KB', 'MB', 'GB', 'TB', 'PB' + for ($x = 0; $x -lt $sizes.count; $x++) { + if ($number -lt [int64]"1$($sizes[$x])") { + if ($x -eq 0) { + return "$number B" + } + else { + $num = $number / [int64]"1$($sizes[$x-1])" + $num = "{0:N2}" -f $num + return "$num $($sizes[$x-1])" + } + } + } + } + $ZipName = $env:ZIP_NAME + $TgzName = $env:TGZ_NAME + $FapNamme = 'SubGHz_Bruteforcer.fap' + $DstFap = "./$FapNamme" + + if (!(Test-Path -Path "dist/f7-C/apps/Sub-GHz/$FapNamme" -PathType Leaf)) { + Write-Error '::error title=Files not found::Cannot find files in location' + exit 1 + } + + $Size = (Get-Item -Path "dist/f7-C/apps/Sub-GHz/$FapNamme" | Get-ItemPropertyValue -Name Length) + Write-Output ('Filesize: {0}' -f (Format-Bytes $Size)) + Copy-Item -Force -Path "dist/f7-C/apps/Sub-GHz/$FapNamme" -Destination $DstFap + + zip -r -qq $ZipName $DstFap + tar zcf $TgzName $DstFap + + if ( !(Test-Path -Path $ZipName -PathType Leaf) -or !(Test-Path -Path $TgzName -PathType Leaf) ) { + Write-Error '::error title=Files not found::Cannot find files in location' + exit 1 + } + + $ZipSize = Format-Bytes (Get-Item -Path $ZipName).Length + $TgzSize = Format-Bytes (Get-Item -Path $TgzName ).Length + + Write-Output ('ZIP_NAME={0}' -f $ZipName) >> $env:GITHUB_ENV + Write-Output ('TGZ_NAME={0}' -f $TgzName ) >> $env:GITHUB_ENV + Write-Output ('ZIP_TAG={0} ({1})' -f $ZipName, $ZipSize) >> $env:GITHUB_ENV + Write-Output ('TGZ_TAG={0} ({1})' -f $TgzName , $TgzSize) >> $env:GITHUB_ENV + - name: Create assets + if: ${{ success() && env.ZIP_NAME != '' }} + env: + GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }} + run: | + gh release upload 'v${{ env.RELEASE_VERSION }}' --clobber \ + '${{ env.ZIP_NAME }}#${{ env.ZIP_TAG }}' '${{ env.TGZ_NAME }}#${{ env.TGZ_TAG }}' -R ${{ env.REPO_SELF }} + gh release edit 'v${{ env.RELEASE_VERSION }}' --draft=false -R ${{ env.REPO_SELF }} + +#EOF diff --git a/.github/workflows/version-check.yml b/.github/workflows/version-check.yml new file mode 100644 index 00000000000..ced41782b2a --- /dev/null +++ b/.github/workflows/version-check.yml @@ -0,0 +1,169 @@ +name: "Version check for NEW release" +run-name: " Version check for NEW release ${{ inputs.DEPLOY_TARGET }} by @${{ github.ACTOR }}" + +on: + workflow_dispatch: + push: + branches: + - master + schedule: + - cron: "*/30 * * * *" + +permissions: + contents: write + +jobs: + pull-request: + concurrency: + group: check-for-new-versions + cancel-in-progress: false + runs-on: ubuntu-latest + env: + REPO_UNLEASHED: ${{ vars.REPO_UNLEASHED }} + RELEASE_VERSION: ${{ vars.RELEASE_VERSION }} + FIRMWARE_VERSION: ${{ vars.FIRMWARE_VERSION }} + REPO_SELF: ${{ vars.REPO_SELF }} + CHECKOUT_DIR: "firmware" + steps: + - name: Copy Repo Files + uses: actions/checkout@v3 + with: + repository: "${{ env.REPO_SELF }}" + path: "${{ env.CHECKOUT_DIR }}" + clean: "true" + submodules: "true" + token: ${{ secrets.FLIPPER_TOKEN }} + - name: Check firmware release + shell: pwsh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + function CleanInput + { + param( + [string] + $DurtyString + ) + return $DurtyString -replace ('[^a-zA-Z\d_\-\,\.\t\n\r\:\;]', '') + } + + $Release = @(` + (CleanInput ` + (gh release list -L 1 --repo '${{ env.REPO_UNLEASHED }}')` + ) -split "`t") + + $FirmwareVersionNumber = 0 + $StoredFirmwareVersionNumber = 0 + if ($Release[2] -match '\-(\d+)$') + { + $FirmwareVersionNumber = [int]($Matches[1]) + } + else + { + Write-Error ('::error title=Invalid firmware number::Error during execution this tags {0}' -f $FirmwareVersionNumber) + exit 1 + } + if ('${{ env.FIRMWARE_VERSION }}' -match '\-(\d+)$') + { + $StoredFirmwareVersionNumber = [int]($Matches[1]) + } + else + { + Write-Error ('::error title=Invalid STORED firmware number::Error during execution this version {0}' -f '${{ env.FIRMWARE_VERSION }}') + exit 1 + } + + $LatestFirmware = CleanInput ((CleanInput (gh release list -L 1 --repo '${{ env.REPO_SELF }}') -replace '\t', ';') | ` + ConvertFrom-Csv -Delimiter ';' -Header name, flag, tag).tag + + $Delta = ( [DateTime]::Now - [DateTime]::Parse($Release[3]) ) + $NewVersionFw = $false + Write-Host ('Latest firmware {0}' -f $LatestFirmware) -ForegroundColor Gray -BackgroundColor Magenta + Write-Debug ('::debug LatestFirmware {0}' -f $LatestFirmware) + + Write-Output ('REMOTE_TAG_INFO=[{0}]({1}/releases/tag/{2})' -f $LatestFirmware, '${{ env.REPO_UNLEASHED }}', $LatestFirmware) >> $env:GITHUB_ENV + if (($FirmwareVersionNumber -gt $StoredFirmwareVersionNumber) -and ( $Delta -gt [TimeSpan]::FromMinutes(10))) + { + Write-Debug ('::debug LatestFirmware {0}' -f $LatestFirmware) + Write-Output ('FIRMWARE_VERSION={0}' -f $LatestFirmware) >> $env:GITHUB_ENV + $NewVersionFw = $true + } + elseif ($FirmwareVersionNumber -lt $StoredFirmwareVersionNumber) + { + Write-Error ('::error title=Invalid check of stored::Version in repo: {0}, but we think it is {1}' -f $FirmwareVersionNumber, $StoredFirmwareVersionNumber) + exit 1 + } + + $LastPublished = (gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" '/repos/${{ vars.REPO_SELF }}/releases?per_page=1' | ConvertFrom-Json).published_at + $Delta = ([DateTime]::Now - $LastPublished) + + $Release = (gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" '/repos/${{ vars.REPO_SELF }}/tags?per_page=1' | ConvertFrom-Json).name + Write-Host ('Release {0}' -f $Release) -ForegroundColor Gray -BackgroundColor Magenta + $LatestTag = $Release.Substring(1) + + $CurrentVersion = [version]::Parse('${{ env.RELEASE_VERSION }}') + $ParsedRepoVersion = [version]::Parse($LatestTag) + Write-Host ('Current tag:Repos tag {0}, {1}' -f $CurrentVersion, $ParsedRepoVersion) -ForegroundColor Gray -BackgroundColor Magenta + Write-Debug ('::debug Current tag:Repos tag {0}, {1}' -f $CurrentVersion, $ParsedRepoVersion) + if (($CurrentVersion -lt $ParsedRepoVersion) -and ( $Delta -gt [TimeSpan]::FromMinutes(10))) + { + $Tag = ('{0}.{1}.{2}' -f $ParsedRepoVersion.Major, $ParsedRepoVersion.Minor, $ParsedRepoVersion.Build) + + Write-Output ('RELEASE_VERSION={0}' -f $Tag) >> $env:GITHUB_ENV + Write-Output ('RELEASE_TYPE=2' -f $Tag) >> $env:GITHUB_ENV + + Write-Output ('::warning title=New release!::Release {0}' -f $Tag) + } + elseif ( $NewVersionFw ) + { + $Tag = ('{0}.{1}.{2}' -f $CurrentVersion.Major, $CurrentVersion.Minor, ($CurrentVersion.Build + 1)) + + Write-Output ('RELEASE_VERSION={0}' -f $Tag) >> $env:GITHUB_ENV + Write-Output ('RELEASE_TYPE=1' -f $Tag) >> $env:GITHUB_ENV + + Write-Output ('::warning title=Firmware was changed!::New version is {0}, creating release {1}' -f $LatestFirmware, $Tag) + } + elseif ( ($Delta -gt [TimeSpan]::FromMinutes(10)) -and ($CurrentVersion -gt $ParsedRepoVersion)) + { + Write-Output ('::warning title=Invalid version!::Version in settings: {0}, but repo version is {1}. Going to change variable' -f $CurrentVersion, $ParsedRepoVersion) + Write-Output ('RELEASE_VERSION={0}' -f $ParsedRepoVersion) >> $env:GITHUB_ENV + Write-Output ('RELEASE_TYPE=3' -f $Tag) >> $env:GITHUB_ENV + } + else + { + # none to release + Write-Host 'No new versions, sorry' + } + Write-Output ('CURRENT_TAG={0}' -f $LatestTag) >> $env:GITHUB_ENV + + - name: Update Firmware variable and create UPDATE release if necessary + if: ${{ success() && env.RELEASE_TYPE == 1 }} + env: + GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }} + OWNER: ${{ github.repository_owner }} + run: | + gh release create 'v${{ env.RELEASE_VERSION }}' --latest --draft \ + --notes 'Rebuild with new version of firmware.\n\nSee: [CHANGELOG](${{ env.FIRMWARE_VERSION }}/blob/dev/CHANGELOG.md)\n${{ env.REMOTE_TAG_INFO}}' \ + --title 'Minor update v${{ env.RELEASE_VERSION }}' --verify-tag -R '${{ env.REPO_SELF }}' + gh variable set FIRMWARE_VERSION -b '${{ env.FIRMWARE_VERSION }}' -R '${{ env.REPO_SELF }}' + gh variable set RELEASE_VERSION -b '${{ env.RELEASE_VERSION }}' -R '${{ env.REPO_SELF }}' + - name: Update release variable and create NEW release if necessary + if: ${{ success() && env.RELEASE_TYPE == 2 }} + env: + GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }} + OWNER: ${{ github.repository_owner }} + run: | + gh release create 'v${{ env.RELEASE_VERSION }}' --notes-start-tag 'v${{ env.CURRENT_TAG }}' --generate-notes --draft --latest \ + --notes 'New version is rolling out!' --verify-tag --title 'Release v${{ env.RELEASE_VERSION }}' -R '${{ env.REPO_SELF }}' + + gh variable set FIRMWARE_VERSION -b '${{ env.FIRMWARE_VERSION }}' -R '${{ env.REPO_SELF }}' + gh variable set RELEASE_VERSION -b '${{ env.RELEASE_VERSION }}' -R '${{ env.REPO_SELF }}' + - name: Current settings in repo invalid. Changing + if: ${{ success() && env.RELEASE_TYPE > 2 }} + env: + GITHUB_TOKEN: ${{ secrets.FLIPPER_TOKEN }} + OWNER: ${{ github.repository_owner }} + run: | + gh variable set RELEASE_VERSION -b ${{ env.RELEASE_VERSION }} -R ${{ env.REPO_SELF }} + +# EOF