name: Build Plugin Component on: workflow_call: inputs: RELEASE_CREATED: type: string required: true description: "Whether a release was created" RELEASE_TAG: type: string required: false description: "Name of the tag when a release is created" TAG: type: string required: false description: "Tag for the build (e.g. PR number or version)" BUCKET_PATH: type: string required: true description: "Path in the bucket where artifacts should be stored" BASE_URL: type: string required: true description: "Base URL for the plugin builds" BUILD_NUMBER: type: string required: true description: "Build number for the plugin builds" ref: type: string required: false description: "Git ref (commit SHA, branch, or tag) to checkout" TRIGGER_PRODUCTION_RELEASE: type: boolean required: false default: false description: "Whether to automatically trigger the release-production workflow (default: false)" secrets: CF_ACCESS_KEY_ID: required: true CF_SECRET_ACCESS_KEY: required: true CF_BUCKET_PREVIEW: required: true CF_ENDPOINT: required: true UNRAID_BOT_GITHUB_ADMIN_TOKEN: required: false jobs: build-plugin: name: Build and Deploy Plugin defaults: run: working-directory: plugin runs-on: ubuntu-latest steps: - name: Checkout repo uses: actions/checkout@v5 with: ref: ${{ inputs.ref }} fetch-depth: 0 - uses: pnpm/action-setup@v4 name: Install pnpm with: run_install: false - name: Install Node uses: actions/setup-node@v5 with: node-version-file: ".nvmrc" cache: 'pnpm' - name: Get 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.json) # For release builds, trust the release tag version to avoid stale checkouts if [ "${{ inputs.RELEASE_CREATED }}" = "true" ] && [ -n "${{ inputs.RELEASE_TAG }}" ]; then TAG_VERSION="${{ inputs.RELEASE_TAG }}" TAG_VERSION="${TAG_VERSION#v}" # trim leading v if present if [ "$TAG_VERSION" != "$PACKAGE_LOCK_VERSION" ]; then echo "::warning::Release tag version ($TAG_VERSION) does not match package.json version ($PACKAGE_LOCK_VERSION). Using tag version for TXZ naming." fi API_VERSION="$TAG_VERSION" else API_VERSION=$([[ -n "$IS_TAGGED" ]] && echo "$PACKAGE_LOCK_VERSION" || echo "${PACKAGE_LOCK_VERSION}+${GIT_SHA}") fi echo "API_VERSION=${API_VERSION}" >> $GITHUB_OUTPUT - name: Install dependencies run: | cd ${{ github.workspace }} pnpm install --frozen-lockfile --filter @unraid/connect-plugin - name: Download Unraid UI Components uses: actions/download-artifact@v5 with: name: unraid-wc-ui path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/uui merge-multiple: true - name: Download Unraid Web Components uses: actions/download-artifact@v5 with: pattern: unraid-wc-rich path: ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/emhttp/plugins/dynamix.my.servers/unraid-components/standalone merge-multiple: true - name: Download Unraid API uses: actions/download-artifact@v5 with: name: unraid-api path: ${{ github.workspace }}/plugin/api/ - name: Extract Unraid API run: | mkdir -p ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/unraid-api tar -xzf ${{ github.workspace }}/plugin/api/unraid-api.tgz -C ${{ github.workspace }}/plugin/source/dynamix.unraid.net/usr/local/unraid-api - name: Build Plugin and TXZ Based on Event and Tag id: build-plugin run: | cd ${{ github.workspace }}/plugin pnpm run build:txz --tag="${{ inputs.TAG }}" --base-url="${{ inputs.BASE_URL }}" --api-version="${{ steps.vars.outputs.API_VERSION }}" --build-number="${{ inputs.BUILD_NUMBER }}" pnpm run build:plugin --tag="${{ inputs.TAG }}" --base-url="${{ inputs.BASE_URL }}" --api-version="${{ steps.vars.outputs.API_VERSION }}" --build-number="${{ inputs.BUILD_NUMBER }}" - name: Ensure Plugin Files Exist run: | ls -al ./deploy if [ ! -f ./deploy/*.plg ]; then echo "Error: .plg file not found in plugin/deploy/" exit 1 fi if [ ! -f ./deploy/*.txz ]; then echo "Error: .txz file not found in plugin/deploy/" exit 1 fi - name: Upload to GHA uses: actions/upload-artifact@v4 with: name: unraid-plugin-${{ github.run_id }}-${{ inputs.RELEASE_TAG }} path: plugin/deploy/ - name: Upload Release Assets if: inputs.RELEASE_CREATED == 'true' env: GITHUB_TOKEN: ${{ github.token }} RELEASE_TAG: ${{ inputs.RELEASE_TAG }} run: | # For each file in release directory for file in deploy/*; do echo "Uploading $file to release..." gh release upload "${RELEASE_TAG}" "$file" --clobber done - name: Workflow Dispatch and wait if: inputs.RELEASE_CREATED == 'true' && inputs.TRIGGER_PRODUCTION_RELEASE == true uses: the-actions-org/workflow-dispatch@v4.0.0 with: workflow: release-production.yml inputs: '{ "version": "v${{ steps.vars.outputs.API_VERSION }}" }' token: ${{ secrets.UNRAID_BOT_GITHUB_ADMIN_TOKEN }} - name: Upload to Cloudflare if: inputs.RELEASE_CREATED == 'false' env: AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: auto run: | # Sync the deploy directory to the Cloudflare bucket with explicit content encoding and public-read ACL aws s3 sync deploy/ s3://${{ secrets.CF_BUCKET_PREVIEW }}/${{ inputs.BUCKET_PATH }} \ --endpoint-url ${{ secrets.CF_ENDPOINT }} \ --checksum-algorithm CRC32 \ --no-guess-mime-type \ --content-encoding none \ --acl public-read - name: Comment URL if: github.event_name == 'pull_request' uses: thollander/actions-comment-pull-request@v3 with: comment-tag: prlink mode: recreate message: | This plugin has been deployed to Cloudflare R2 and is available for testing. Download it at this URL: ``` ${{ inputs.BASE_URL }}/tag/${{ inputs.TAG }}/dynamix.unraid.net.plg ``` - name: Clean up old preview builds if: inputs.RELEASE_CREATED == 'false' && github.event_name == 'push' continue-on-error: true env: AWS_ACCESS_KEY_ID: ${{ secrets.CF_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: auto run: | echo "🧹 Cleaning up old preview builds (keeping last 7 days)..." # Calculate cutoff date (7 days ago) CUTOFF_DATE=$(date -d "7 days ago" +"%Y.%m.%d") echo "Deleting builds older than: ${CUTOFF_DATE}" # List and delete old timestamped .txz files OLD_FILES=$(aws s3 ls "s3://${{ secrets.CF_BUCKET_PREVIEW }}/unraid-api/" \ --endpoint-url ${{ secrets.CF_ENDPOINT }} --recursive | \ grep -E "dynamix\.unraid\.net-[0-9]{4}\.[0-9]{2}\.[0-9]{2}\.[0-9]{4}\.txz" | \ awk '{print $4}' || true) DELETED_COUNT=0 if [ -n "$OLD_FILES" ]; then while IFS= read -r file; do if [[ $file =~ ([0-9]{4}\.[0-9]{2}\.[0-9]{2})\.[0-9]{4}\.txz ]]; then FILE_DATE="${BASH_REMATCH[1]}" if [[ "$FILE_DATE" < "$CUTOFF_DATE" ]]; then echo "Deleting old build: $(basename "$file")" aws s3 rm "s3://${{ secrets.CF_BUCKET_PREVIEW }}/${file}" \ --endpoint-url ${{ secrets.CF_ENDPOINT }} || true ((DELETED_COUNT++)) fi fi done <<< "$OLD_FILES" fi echo "✅ Deleted ${DELETED_COUNT} old builds"