name: CI - Main (API) on: pull_request: push: branches: - main tags: - "v*" concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: release-please: if: startsWith(github.ref, 'refs/tags/') runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - id: release uses: googleapis/release-please-action@v4 outputs: releases_created: ${{ steps.release.outputs.releases_created }} tag_name: ${{ steps.release.outputs.tag_name }} start: # This prevents a tag running twice as it'll have a "tag" and a "commit" event # We only want the tag to run the action as it'll be able to create the release notes if: (startsWith(github.event.ref, 'refs/heads/') && !startsWith(github.event.head_commit.message, 'chore(release)')) || (startsWith(github.event.ref, 'refs/tags/') && startsWith(github.event.head_commit.message, 'chore(release)')) runs-on: ubuntu-latest steps: - name: Validate branch and tag run: exit 0 build-test-api: name: Build and Test API runs-on: ubuntu-latest defaults: run: working-directory: api outputs: API_VERSION: ${{ steps.vars.outputs.API_VERSION }} API_MD5: ${{ steps.set-hashes.outputs.API_MD5 }} API_SHA256: ${{ steps.set-hashes.outputs.API_SHA256 }} steps: - name: Checkout repo uses: actions/checkout@v4 - name: Build with Buildx uses: docker/setup-buildx-action@v3 with: install: true platforms: linux/amd64 - name: Build Builder uses: docker/build-push-action@v6 with: context: ./api push: false tags: builder:latest cache-from: type=gha,ref=builder:latest cache-to: type=gha,mode=max,ref=builder:latest load: true - name: Lint inside of the docker container continue-on-error: true run: | docker run --rm builder npm run lint - name: Test inside of the docker container run: | git fetch --depth=2 origin main if git diff --name-only --relative=api origin/main HEAD | grep -q '.'; then docker run --rm builder npm run coverage else echo "No changes in /api folder, skipping coverage." fi - name: Get Git Short Sha and API version id: vars run: | GIT_SHA=$(git rev-parse --short HEAD) IS_TAGGED=$(git describe --tags --abbrev=0 --exact-match || echo '') PACKAGE_LOCK_VERSION=$(jq -r '.version' package-lock.json) echo "GIT_SHA=$GIT_SHA" >> $GITHUB_OUTPUT echo "IS_TAGGED=$IS_TAGGED" >> $GITHUB_OUTPUT echo "PACKAGE_LOCK_VERSION=$PACKAGE_LOCK_VERSION" >> $GITHUB_OUTPUT echo "API_VERSION=$([[ -n "$IS_TAGGED" ]] && echo "$PACKAGE_LOCK_VERSION" || echo "${PACKAGE_LOCK_VERSION}+${GIT_SHA}")" >> $GITHUB_OUTPUT - name: Build inside of the docker container id: build-pack-binary run: | docker run --rm -v ${{ github.workspace }}/api/deploy/release:/app/deploy/release -e API_VERSION=${{ steps.vars.outputs.API_VERSION }} builder npm run build-and-pack - name: Set Hashes id: set-hashes run: | echo "API_MD5=$(md5sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')" >> $GITHUB_OUTPUT echo "API_SHA256=$(sha256sum ${{ github.workspace }}/api/deploy/release/*.tgz | awk '{ print $1 }')" >> $GITHUB_OUTPUT - name: Upload tgz to Github artifacts uses: actions/upload-artifact@v4 with: name: unraid-api path: ${{ github.workspace }}/api/deploy/release/*.tgz build-web: name: Build Web App environment: name: production defaults: run: working-directory: web runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v4 - name: Create env file run: | touch .env echo VITE_ACCOUNT=${{ vars.VITE_ACCOUNT }} >> .env echo VITE_CONNECT=${{ vars.VITE_CONNECT }} >> .env echo VITE_UNRAID_NET=${{ vars.VITE_UNRAID_NET }} >> .env echo VITE_CALLBACK_KEY=${{ vars.VITE_CALLBACK_KEY }} >> .env cat .env - name: Install node uses: actions/setup-node@v4 with: cache: "npm" cache-dependency-path: "web/package-lock.json" node-version-file: "web/.nvmrc" - name: Installing node deps run: npm install - name: Lint files continue-on-error: true run: npm run lint - name: Test run: npm run test:ci - name: Build run: npm run build - name: Upload build to Github artifacts uses: actions/upload-artifact@v4 with: name: unraid-web path: web/.nuxt/nuxt-custom-elements/dist/unraid-components build-plugin: needs: [build-test-api, build-web] defaults: run: working-directory: plugin runs-on: ubuntu-latest steps: - name: Set Timezone uses: szenius/set-timezone@v1.2 with: timezoneLinux: "America/Los_Angeles" - name: Checkout repo uses: actions/checkout@v4 - name: Download unraid web components uses: actions/download-artifact@v4 with: name: unraid-web path: ./plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components - name: Download Node.js From Slackbuilds (skipped due to node.js issues) if: false id: download-nodejs run: | # Get latest node version (based on main_node_version) from slackware main_node_version=$(sed 's/^v//' ../api/.nvmrc) base_node_url="https://mirrors.slackware.com/slackware/slackware64-current/slackware64/l/" latest_nodejs=$(wget -q -O- "${base_node_url}" | grep -o "nodejs-${main_node_version}\.[0-9.]*-x86_64-[0-9]*\.txz" | sort -V | tail -n 1) if [[ -z "${latest_nodejs}" ]]; then echo "Error: Failed to fetch the latest nodejs version." exit 1 fi node_download_url="${base_node_url}${latest_nodejs}" if ! wget -q "${node_download_url}" -O "${{ github.workspace }}/plugin/archive/${latest_nodejs}"; then echo "Error: Failed to download nodejs package." exit 1 fi node_sha256=$(sha256sum "${{ github.workspace }}/plugin/archive/${latest_nodejs}" | cut -f 1 -d ' ') echo "NODEJS_FILENAME=${latest_nodejs}" >> $GITHUB_OUTPUT echo "NODEJS_SHA256=${node_sha256}" >> $GITHUB_OUTPUT - name: Download nghttp3 id: download-nghttp3 run: | # Get latest nghttp3 version base_nghttp3_url="https://mirrors.slackware.com/slackware/slackware64-current/slackware64/n/" latest_nghttp3=$(wget -q -O- "${base_nghttp3_url}" | grep -o "nghttp3-[0-9.]*-x86_64-[0-9]*\.txz" | sort -V | tail -n 1) nghttp3_download_url="${base_nghttp3_url}${latest_nghttp3}" if ! wget -q "${nghttp3_download_url}" -O "${{ github.workspace }}/plugin/archive/${latest_nghttp3}"; then echo "Error: Failed to download nghttp3 package." exit 1 fi nghttp3_sha256=$(sha256sum "${{ github.workspace }}/plugin/archive/${latest_nghttp3}" | cut -f 1 -d ' ') echo "NGHTTP3_FILENAME=${latest_nghttp3}" >> $GITHUB_OUTPUT echo "NGHTTP3_SHA256=${nghttp3_sha256}" >> $GITHUB_OUTPUT - name: Build Plugin run: | cd source/dynamix.unraid.net export API_VERSION=${{needs.build-test-api.outputs.API_VERSION}} export API_MD5=${{needs.build-test-api.outputs.API_MD5}} export API_SHA256=${{needs.build-test-api.outputs.API_SHA256}} export NGHTTP3_FILENAME=${{ steps.download-nghttp3.outputs.NGHTTP3_FILENAME }} export NGHTTP3_SHA256=${{ steps.download-nghttp3.outputs.NGHTTP3_SHA256 }} if [ -z "${API_VERSION}" ] || [ -z "${API_MD5}" ] || [ -z "${API_SHA256}" ] || [ -z "${NGHTTP3_FILENAME}" ] || [ -z "${NGHTTP3_SHA256}" ]; then echo "Error: One or more required variables are not set." exit 1 fi bash ./pkg_build.sh s ${{github.event.pull_request.number}} bash ./pkg_build.sh p - name: Upload binary txz and plg to Github artifacts uses: actions/upload-artifact@v4 with: name: connect-files path: | ${{ github.workspace }}/plugin/archive/*.txz ${{ github.workspace }}/plugin/plugins/*.plg retention-days: 5 if-no-files-found: error release-pull-request: if: | github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' runs-on: ubuntu-latest needs: [build-plugin] steps: - name: Checkout repo uses: actions/checkout@v4 - name: Make PR Release Folder run: mkdir pr-release/ - name: Download unraid-api binary tgz uses: actions/download-artifact@v4 with: name: unraid-api path: pr-release - name: Download plugin binary tgz uses: actions/download-artifact@v4 with: name: connect-files - name: Write Changelog to Plugin XML run: | # Capture the pull request number and latest commit message pr_number="${{ github.event.pull_request.number }}" commit_message=$(git log -1 --pretty=%B) # Clean up newlines, escape special characters, and handle line breaks notes=$(echo -e "Pull Request Build: ${pr_number}\n${commit_message}" | \ sed ':a;N;$!ba;s/\n/\\n/g' | \ sed -e 's/[&\\/]/\\&/g') # Replace tag content in the file sed -i -z -E "s/(.*)<\/CHANGES>/\n${notes}\n<\/CHANGES>/g" "plugins/dynamix.unraid.net.staging.plg" - name: Copy other release files to pr-release run: | cp archive/*.txz pr-release/ cp plugins/dynamix.unraid.net.staging.plg pr-release/ - name: Upload to Cloudflare uses: jakejarvis/s3-sync-action@v0.5.1 env: AWS_S3_ENDPOINT: ${{ secrets.CF_ENDPOINT }} AWS_S3_BUCKET: ${{ secrets.CF_BUCKET_PREVIEW }} AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }} AWS_REGION: "auto" SOURCE_DIR: pr-release DEST_DIR: unraid-api/pr/${{ github.event.pull_request.number }} - name: Comment URL uses: thollander/actions-comment-pull-request@v3 with: message: | This plugin has been deployed to Cloudflare R2 and is available for testing. Download it at this URL: [https://preview.dl.unraid.net/unraid-api/pr/${{ github.event.pull_request.number }}/dynamix.unraid.net.staging.plg](https://preview.dl.unraid.net/unraid-api/pr/${{ github.event.pull_request.number }}/dynamix.unraid.net.staging.plg) release-staging: environment: name: staging # Only release if this is a push to the main branch if: startsWith(github.ref, 'refs/heads/main') runs-on: ubuntu-latest needs: [build-plugin] steps: - name: Checkout repo uses: actions/checkout@v4 - name: Make Staging Release Folder run: mkdir staging-release/ - name: Download unraid-api binary tgz uses: actions/download-artifact@v4 with: name: unraid-api path: staging-release - name: Download plugin binary tgz uses: actions/download-artifact@v4 with: name: connect-files - name: Parse Changelog id: changelog uses: ocavue/changelog-parser-action@v1 with: removeMarkdown: false filePath: "./api/CHANGELOG.md" - name: Copy Files for Staging Release run: | cp archive/*.txz staging-release/ cp plugins/dynamix.unraid.net.staging.plg staging-release/ ls -al staging-release - name: Upload Staging Plugin to DO Spaces uses: BetaHuhn/do-spaces-action@v2 with: access_key: ${{ secrets.DO_ACCESS_KEY }} secret_key: ${{ secrets.DO_SECRET_KEY }} space_name: ${{ secrets.DO_SPACE_NAME }} space_region: ${{ secrets.DO_SPACE_REGION }} source: staging-release out_dir: unraid-api - name: Upload Staging Plugin to Cloudflare Bucket uses: jakejarvis/s3-sync-action@v0.5.1 env: AWS_S3_ENDPOINT: ${{ secrets.CF_ENDPOINT }} AWS_S3_BUCKET: ${{ secrets.CF_BUCKET_PREVIEW }} AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }} AWS_REGION: "auto" SOURCE_DIR: staging-release DEST_DIR: unraid-api create-draft-release: # Only create new draft if this is a version tag if: | startsWith(github.ref, 'refs/tags/v') runs-on: ubuntu-latest needs: [build-plugin] steps: - name: Checkout repo uses: actions/checkout@v4 - name: Download unraid-api binary tgz uses: actions/download-artifact@v4 with: name: unraid-api - name: Download plugin binary tgz uses: actions/download-artifact@v4 with: name: connect-files - name: Create Github release uses: softprops/action-gh-release@v1 with: draft: true prerelease: false files: | unraid-api-*.tgz plugins/dynamix.unraid.net* archive/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}