name: ci on: push: branches: [main] paths-ignore: ['**.md'] pull_request: branches: [main] paths-ignore: ['**.md'] release: types: [published] env: ARTIFACT_DIR: .artifacts ARTIFACT_RETENTION_DAYS: 5 defaults: run: shell: bash jobs: version: runs-on: ubuntu-latest outputs: TAG: ${{ steps.tag.outputs.TAG }} steps: - name: Checkout uses: actions/checkout@v6 with: ref: main fetch-depth: ${{ startsWith(github.ref, 'refs/tags/v') && '0' || '1' }} - name: Get tag if tagged/released and set TAG env var if: ${{ startsWith(github.ref, 'refs/tags/v') }} run: | TAG="$GITHUB_REF_NAME" if [[ $TAG == "v"* ]]; then TAG="${TAG:1}" fi { echo "TAG=$TAG" } | tee -a "$GITHUB_ENV" - name: Update VERSION in version file and push if: ${{ startsWith(github.ref, 'refs/tags/v') }} run: | VERSION_FILE="./src/version.hpp" OLD_TAG=$(grep VERSION $VERSION_FILE | cut -d ' ' -f3 | tr -d '"' | tr -d '\n') echo "OLD_TAG: $OLD_TAG" NEW_TAG="$TAG" echo "NEW_TAG: $NEW_TAG" if [[ "$NEW_TAG" == "$OLD_TAG" ]]; then echo "Old and new tags are the same! No update required!" else echo "Updating VERSION in version file [$OLD_TAG => $NEW_TAG]" sed -i -e "s|VERSION .*|VERSION \"$NEW_TAG\"|" $VERSION_FILE git config --global user.name 'Azeem Sajid' git config --global user.email 'iamAzeem@users.noreply.github.com' git diff "$VERSION_FILE" git add "$VERSION_FILE" git commit -m "Automatic version update from $OLD_TAG to $NEW_TAG." git push echo "Version updated successfully!" fi - name: Set TAG output parameter id: tag run: | VERSION_FILE="./src/version.hpp" TAG=$(grep VERSION $VERSION_FILE | cut -d ' ' -f3 | tr -d '"' | tr -d '\n') { echo "TAG=$TAG" } | tee -a "$GITHUB_OUTPUT" ci: needs: [version] strategy: matrix: config: - os: ubuntu-latest prefix: amd64-linux cxx: g++ strip: strip tests: true - os: ubuntu-latest prefix: arm64-linux cxx: aarch64-linux-gnu-g++ strip: aarch64-linux-gnu-strip tests: false - os: ubuntu-latest prefix: amd64-windows cxx: x86_64-w64-mingw32-g++ strip: x86_64-w64-mingw32-strip tests: false - os: macos-15-intel prefix: amd64-macosx cxx: clang++ strip: strip tests: true - os: macos-latest prefix: arm64-macosx cxx: clang++ strip: strip tests: true runs-on: ${{ matrix.config.os }} env: TAG: ${{ needs.version.outputs.TAG }} PREFIX: ${{ matrix.config.prefix }} CXX: ${{ matrix.config.cxx }} STRIP: ${{ matrix.config.strip }} TESTS: ${{ matrix.config.tests }} TAR: spancopy-${{ needs.version.outputs.TAG }}-${{ matrix.config.prefix }}.tar.gz ZIP: spancopy-${{ needs.version.outputs.TAG }}-${{ matrix.config.prefix }}.zip steps: - name: Checkout uses: actions/checkout@v6 with: ref: ${{ startsWith(github.ref, 'refs/tags/v') && 'main' || '' }} - name: Install dependencies (ARM64 Linux | AMD64 Windows) if: ${{ env.PREFIX == 'arm64-linux' || env.PREFIX == 'amd64-windows' }} env: ARM64_LINUX: ${{ env.PREFIX == 'arm64-linux' && 'g++-aarch64-linux-gnu' || '' }} AMD64_WINDOWS: ${{ env.PREFIX == 'amd64-windows' && 'g++-mingw-w64' || '' }} run: | sudo apt update sudo apt install -y $ARM64_LINUX $AMD64_WINDOWS - name: Build (${{ env.PREFIX }}) run: ./scripts/ci-build.bash - name: Test (${{ env.PREFIX }}) if: ${{ env.TESTS == 'true' }} run: ./tests/test.bash - name: Upload (${{ env.TAR }}) uses: actions/upload-artifact@v6 with: name: ${{ env.TAR }} path: ${{ env.ARTIFACT_DIR }}/${{ env.TAR }} retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }} if-no-files-found: error - name: Upload (${{ env.ZIP }}) uses: actions/upload-artifact@v6 with: name: ${{ env.ZIP }} path: ${{ env.ARTIFACT_DIR }}/${{ env.ZIP }} retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }} if-no-files-found: error - name: Upload release artifacts if: ${{ startsWith(github.ref, 'refs/tags/v') }} env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./scripts/ci-upload-release-artifacts.bash publish-winget-package: if: ${{ github.event_name == 'release' && github.event.action == 'published' }} needs: [version, ci] runs-on: windows-latest steps: - name: Install wingetcreate run: | curl -L https://aka.ms/wingetcreate/latest -o wingetcreate chmod +x wingetcreate ./wingetcreate info - name: Update env: TAG: ${{ needs.version.outputs.TAG }} PAT: ${{ secrets.SPANCOPY_WINGET_PAT }} PKG_ID: "iamAzeem.spancopy" run: | URL="https://github.com/iamazeem/spancopy/releases/download/v$TAG/spancopy-$TAG-amd64-windows.zip" ./wingetcreate update "$PKG_ID" \ --version "$TAG" \ --urls "$URL" \ --out "$GITHUB_WORKSPACE/manifests" \ --token "$PAT" \ --prtitle "New version: $PKG_ID v$TAG" \ --submit - name: Upload manifest uses: actions/upload-artifact@v6 with: name: spancopy-winget-manifest path: ${{ github.workspace }}/manifests retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }} if-no-files-found: error prepare-linux-packages: if: ${{ github.event_name == 'release' && github.event.action == 'published' }} needs: [version, ci] runs-on: ubuntu-latest env: TAG: ${{ needs.version.outputs.TAG }} AMD64_ZIP: spancopy-${{ needs.version.outputs.TAG }}-amd64-linux.zip ARM64_ZIP: spancopy-${{ needs.version.outputs.TAG }}-arm64-linux.zip AMD64_DEB: spancopy_${{ needs.version.outputs.TAG }}_amd64.deb ARM64_DEB: spancopy_${{ needs.version.outputs.TAG }}_arm64.deb AMD64_RPM: spancopy-${{ needs.version.outputs.TAG }}-1.x86_64.rpm ARM64_RPM: spancopy-${{ needs.version.outputs.TAG }}-1.aarch64.rpm steps: - name: Checkout .fpm config file uses: actions/checkout@v6 with: sparse-checkout: | .fpm packages - name: Download ZIP artifacts uses: actions/download-artifact@v7 with: pattern: spancopy-${{ env.TAG }}-*-linux.zip path: ${{ env.ARTIFACT_DIR }} merge-multiple: true - name: Install dependencies run: | sudo apt update sudo apt install -y rpm dpkg-dev createrepo-c sudo gem install --no-document fpm - name: Build DEB packages run: | cd "$ARTIFACT_DIR" ls -hl *.zip fpm \ --fpm-options-file ../.fpm \ --architecture "amd64" \ --version "$TAG" \ "$AMD64_ZIP" dpkg --info "$AMD64_DEB" dpkg --contents "$AMD64_DEB" fpm \ --fpm-options-file ../.fpm \ --architecture "arm64" \ --version "$TAG" \ "$ARM64_ZIP" dpkg --info "$ARM64_DEB" dpkg --contents "$ARM64_DEB" ls -hl *.deb - name: Build RPM packages run: | cd "$ARTIFACT_DIR" ls -hl *.zip fpm \ --fpm-options-file ../.fpm \ --output-type rpm \ --architecture "amd64" \ --version "$TAG" \ "$AMD64_ZIP" rpm -qip "$AMD64_RPM" rpm -qlp "$AMD64_RPM" fpm \ --fpm-options-file ../.fpm \ --output-type rpm \ --architecture "arm64" \ --version "$TAG" \ "$ARM64_ZIP" rpm -qip "$ARM64_RPM" rpm -qlp "$ARM64_RPM" ls -hl *.rpm - name: Move deb and rpm files to packages directory run: | mkdir -p packages/{apt,rpm}/{amd64,arm64} mv "$ARTIFACT_DIR/$AMD64_DEB" packages/apt/amd64/ mv "$ARTIFACT_DIR/$ARM64_DEB" packages/apt/arm64/ mv "$ARTIFACT_DIR/$AMD64_RPM" packages/rpm/amd64/ mv "$ARTIFACT_DIR/$ARM64_RPM" packages/rpm/arm64/ ls -hl packages/{apt,rpm}/{amd64,arm64} - name: Update APT repository run: | for ARCH in amd64 arm64; do cd packages/apt/"$ARCH" dpkg-scanpackages . /dev/null > Packages gzip -k -f Packages apt-ftparchive release . > Release cd - done - name: Update RPM repository run: | for ARCH in amd64 arm64; do createrepo_c packages/rpm/"$ARCH" done - name: Upload GitHub Pages artifacts uses: actions/upload-pages-artifact@v4 with: name: packages path: packages publish-linux-packages: if: ${{ github.ref_name == 'main' || startsWith(github.ref, 'refs/tags/v') }} needs: [prepare-linux-packages] runs-on: ubuntu-latest permissions: pages: write id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 with: artifact_name: packages