name: Publish on: pull_request: paths: - 'native/**' - '.github/workflows/native-build.yml' - '.github/workflows/native-release.yml' - '.github/workflows/native-update.yml' - '.github/workflows/publish.yml' - 'package.json' - 'swama/Project/**' - 'swama/Resources/**' push: branches: - main paths: - '*/Project/Sources/**/*.4dm' - '*/Project/Sources/*/*.4DForm' - '*/Project/Sources/*.4DCatalog' - '*/Project/Resources/**' workflow_dispatch: inputs: use_self_hosted: type: boolean description: use self-hosted ARM64 runner for 4D packaging from committed native resources required: true default: false mode: type: choice description: semantic versioning options: - patch - minor - major required: true permissions: contents: read env: project_path: swama/Project/swama.4DProject concurrency: group: swama-component-${{ github.event_name == 'pull_request' && github.ref || 'publish' }} cancel-in-progress: false jobs: publish: if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/main' && github.event.repository.default_branch == 'main' && github.event.inputs.use_self_hosted != 'true' }} permissions: contents: write runs-on: macos-26 timeout-minutes: 75 steps: - name: configure id: configure uses: miyako/4D/.github/actions/bash/configure@v1 with: mode: ${{ inputs.mode || 'patch' }} - name: checkout uses: actions/checkout@v4 with: ref: ${{ github.sha }} persist-credentials: true - uses: actions/setup-python@v5 with: python-version: '3.12' - name: Require current default-branch commit run: python3 native/update.py freshness --expected "$GITHUB_SHA" - name: Verify committed native resources and provenance run: python3 native/update.py verify - name: set version id: version env: RELEASE_MODE: ${{ steps.configure.outputs.mode }} GH_TOKEN: ${{ github.token }} run: python3 native/release.py version --mode "$RELEASE_MODE" - name: Prepare verified native resources for component signing run: python3 native/update.py prepare-component - name: get tool version id: tool uses: miyako/4D/.github/actions/tool4d-get-version@v1 - name: get tool4d id: get uses: miyako/4D/.github/actions/tool4d-download@v1 with: platform: ${{ steps.tool.outputs.platform }} branch: ${{ steps.tool.outputs.branch }} version: ${{ steps.tool.outputs.version }} build: ${{ steps.tool.outputs.build }} arch: ${{ steps.tool.outputs.arch }} - name: Resolve pinned 4D dependencies and verify compilation run: python3 native/component.py --tool tool4d.app/Contents/MacOS/tool4d - name: build id: build uses: miyako/4D/.github/actions/build-component@v1 with: project_path: ${{ steps.configure.outputs.project_path }} pack_project: 'true' use_standard_zip: 'true' - name: setup keychain id: keychain uses: miyako/4D/.github/actions/deployment-setup-keychain@v1 with: APPLE_DEVELOPER_ID_CERTIFICATE: ${{ secrets.APPLE_DEVELOPER_ID_CERTIFICATE }} APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - name: Sign, require Accepted notarization and verify final distributions env: PRODUCT_PATH: ${{ steps.build.outputs.product_path }} COMPONENT_VERSION: ${{ steps.version.outputs.version }} SIGN_IDENTITY: ${{ secrets.CODESIGN_APPLE_ID }} SIGN_KEYCHAIN: ${{ steps.keychain.outputs.KEYCHAIN_PATH }} NOTARY_APPLE_ID: ${{ secrets.NOTARYTOOL_APPLE_ID }} NOTARY_TEAM: ${{ secrets.NOTARYTOOL_TEAM_ID }} NOTARY_PASSWORD: ${{ secrets.NOTARYTOOL_PASSWORD }} run: python3 native/release.py package "$PRODUCT_PATH" "$COMPONENT_VERSION" - name: Publish new verified release without overwriting tags or assets env: COMPONENT_VERSION: ${{ steps.version.outputs.version }} GH_TOKEN: ${{ github.token }} run: python3 native/release.py publish "$COMPONENT_VERSION" - name: Retain release verification evidence if: always() uses: actions/upload-artifact@v4 with: name: component-release-evidence-hosted path: dist/component/ if-no-files-found: ignore retention-days: 30 publish-locally: if: ${{ github.event_name != 'pull_request' && github.ref == 'refs/heads/main' && github.event.repository.default_branch == 'main' && github.event.inputs.use_self_hosted == 'true' }} permissions: contents: write runs-on: [self-hosted, macos, ARM64] timeout-minutes: 75 steps: - name: configure id: configure uses: miyako/4D/.github/actions/bash/configure@v1 with: mode: ${{ inputs.mode || 'patch' }} - name: checkout uses: actions/checkout@v4 with: ref: ${{ github.sha }} persist-credentials: true - uses: actions/setup-python@v5 with: python-version: '3.12' - name: Require current default-branch commit run: python3 native/update.py freshness --expected "$GITHUB_SHA" - name: Verify committed native resources and provenance run: python3 native/update.py verify - name: set version id: version env: RELEASE_MODE: ${{ steps.configure.outputs.mode }} GH_TOKEN: ${{ github.token }} run: python3 native/release.py version --mode "$RELEASE_MODE" - name: Prepare verified native resources for component signing run: python3 native/update.py prepare-component - name: get tool version id: tool uses: miyako/4D/.github/actions/tool4d-get-version@v1 - name: get tool4d id: get uses: miyako/4D/.github/actions/tool4d-download@v1 with: platform: ${{ steps.tool.outputs.platform }} branch: ${{ steps.tool.outputs.branch }} version: ${{ steps.tool.outputs.version }} build: ${{ steps.tool.outputs.build }} arch: ${{ steps.tool.outputs.arch }} - name: Resolve pinned 4D dependencies and verify compilation run: python3 native/component.py --tool tool4d.app/Contents/MacOS/tool4d - name: build id: build uses: miyako/4D/.github/actions/build-component@v1 with: project_path: ${{ steps.configure.outputs.project_path }} pack_project: 'true' use_standard_zip: 'true' - name: setup keychain id: keychain uses: miyako/4D/.github/actions/deployment-setup-keychain@v1 with: APPLE_DEVELOPER_ID_CERTIFICATE: ${{ secrets.APPLE_DEVELOPER_ID_CERTIFICATE }} APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_DEVELOPER_ID_CERTIFICATE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - name: Sign, require Accepted notarization and verify final distributions env: PRODUCT_PATH: ${{ steps.build.outputs.product_path }} COMPONENT_VERSION: ${{ steps.version.outputs.version }} SIGN_IDENTITY: ${{ secrets.CODESIGN_APPLE_ID }} SIGN_KEYCHAIN: ${{ steps.keychain.outputs.KEYCHAIN_PATH }} NOTARY_APPLE_ID: ${{ secrets.NOTARYTOOL_APPLE_ID }} NOTARY_TEAM: ${{ secrets.NOTARYTOOL_TEAM_ID }} NOTARY_PASSWORD: ${{ secrets.NOTARYTOOL_PASSWORD }} run: python3 native/release.py package "$PRODUCT_PATH" "$COMPONENT_VERSION" - name: Publish new verified release without overwriting tags or assets env: COMPONENT_VERSION: ${{ steps.version.outputs.version }} GH_TOKEN: ${{ github.token }} run: python3 native/release.py publish "$COMPONENT_VERSION" - name: Retain release verification evidence if: always() uses: actions/upload-artifact@v4 with: name: component-release-evidence-self-hosted path: dist/component/ if-no-files-found: ignore retention-days: 30 component-check: name: Verify unsigned 4D component if: github.event_name == 'pull_request' permissions: contents: read runs-on: macos-26 timeout-minutes: 30 steps: - uses: actions/checkout@v4 with: persist-credentials: false - uses: actions/setup-python@v5 with: python-version: '3.12' - name: Run packaging regression tests run: python3 -m unittest discover -s native -p 'test_*.py' - name: Verify committed native resources and provenance run: python3 native/update.py verify - name: Read tool4d version id: tool uses: miyako/4D/.github/actions/tool4d-get-version@v1 with: build_project_name: swama - name: Download tool4d uses: miyako/4D/.github/actions/tool4d-download@v1 with: platform: ${{ steps.tool.outputs.platform }} branch: ${{ steps.tool.outputs.branch }} version: ${{ steps.tool.outputs.version }} build: ${{ steps.tool.outputs.build }} arch: ${{ steps.tool.outputs.arch }} - name: Resolve pinned 4D dependencies and verify compilation run: python3 native/component.py --tool tool4d.app/Contents/MacOS/tool4d - name: Compile and package without version bump or signing id: component uses: miyako/4D/.github/actions/build-component@v1 with: project_path: ${{ github.workspace }}/swama/Project/swama.4DProject pack_project: 'true' use_standard_zip: 'true' - name: Verify actual component output and native resources env: PRODUCT_PATH: ${{ steps.component.outputs.product_path }} run: | test -d "$PRODUCT_PATH" test -n "$(find "$PRODUCT_PATH" -iname '*.4dz' -type f -print -quit)" python3 native/smoke.py "$PRODUCT_PATH/Resources/bin/macOS" git diff --exit-code -- package.json native/upstream.json tar -czf .native-build/swama-component-validation.tar.gz -C "$(dirname "$PRODUCT_PATH")" "$(basename "$PRODUCT_PATH")" - uses: actions/upload-artifact@v4 with: name: swama-component-validation-macos-arm64 path: .native-build/swama-component-validation.tar.gz if-no-files-found: error retention-days: 14