From 6ccc00f5c142103a0427f07f373074daa0491ae3 Mon Sep 17 00:00:00 2001 From: Diego Tavares Date: Wed, 8 Oct 2025 14:00:36 -0700 Subject: [PATCH 1/4] [CICD] Remove published whls from release (#2034) ASWF created a discussion group to come up with a process to release binaries. While this effort is ongoing, we were advised to avoid publishing binaries on github when possible. --- .github/workflows/release-pipeline.yml | 161 +++++++++++++------------ 1 file changed, 82 insertions(+), 79 deletions(-) diff --git a/.github/workflows/release-pipeline.yml b/.github/workflows/release-pipeline.yml index 0602b504b..ff57d9e6d 100644 --- a/.github/workflows/release-pipeline.yml +++ b/.github/workflows/release-pipeline.yml @@ -353,85 +353,88 @@ jobs: asset_name: opencue-cuebot-${{ env.BUILD_ID }}-1.noarch.rpm asset_content_type: application/octet-stream - - name: Upload RQD package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_rqd-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: rqd-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream - - - name: Upload CueGUI package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_cuegui-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: cuegui-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream - - - name: Upload PyCue package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_pycue-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: pycue-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream - - - name: Upload PyOutline package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_pyoutline-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: pyoutline-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream - - - name: Upload CueSubmit package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_cuesubmit-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: cuesubmit-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream - - - name: Upload CueAdmin package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_cueadmin-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: cueadmin-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream - - - name: Upload CueMan package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_cueman-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: cueman-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream - - - name: Upload CueNIMBY package - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ${{ github.workspace }}/artifacts/opencue_cuenimby-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_name: cuenimby-${{ env.BUILD_ID }}-py2.py3-none-any.whl - asset_content_type: application/octet-stream + # Pause python artifact releases for now while ASWF discusses the implications of publishing + # binary artifacts + # + # - name: Upload RQD package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_rqd-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: rqd-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream + + # - name: Upload CueGUI package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_cuegui-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: cuegui-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream + + # - name: Upload PyCue package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_pycue-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: pycue-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream + + # - name: Upload PyOutline package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_pyoutline-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: pyoutline-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream + + # - name: Upload CueSubmit package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_cuesubmit-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: cuesubmit-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream + + # - name: Upload CueAdmin package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_cueadmin-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: cueadmin-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream + + # - name: Upload CueMan package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_cueman-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: cueman-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream + + # - name: Upload CueNIMBY package + # uses: actions/upload-release-asset@v1 + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # with: + # upload_url: ${{ steps.create_release.outputs.upload_url }} + # asset_path: ${{ github.workspace }}/artifacts/opencue_cuenimby-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_name: cuenimby-${{ env.BUILD_ID }}-py2.py3-none-any.whl + # asset_content_type: application/octet-stream - name: Upload openrqd (Linux GNU) uses: actions/upload-release-asset@v1 From 2ddfe88230f237e83fe52ea2b0d5c74fb5615d05 Mon Sep 17 00:00:00 2001 From: Alexis Oblet Date: Mon, 23 Mar 2026 11:06:39 +0100 Subject: [PATCH 2/4] layer dispatch order: backend implementation --- .../java/com/imageworks/spcue/dao/LayerDao.java | 9 +++++++++ .../imageworks/spcue/dao/postgres/LayerDaoJdbc.java | 9 +++++++++ .../com/imageworks/spcue/servant/ManageLayer.java | 13 +++++++++++++ .../com/imageworks/spcue/service/JobManager.java | 8 ++++++++ .../imageworks/spcue/service/JobManagerService.java | 5 +++++ proto/src/job.proto | 10 ++++++++++ pycue/opencue/wrappers/layer.py | 11 +++++++++++ 7 files changed, 65 insertions(+) diff --git a/cuebot/src/main/java/com/imageworks/spcue/dao/LayerDao.java b/cuebot/src/main/java/com/imageworks/spcue/dao/LayerDao.java index 5d5433ada..a82846e14 100644 --- a/cuebot/src/main/java/com/imageworks/spcue/dao/LayerDao.java +++ b/cuebot/src/main/java/com/imageworks/spcue/dao/LayerDao.java @@ -127,6 +127,15 @@ public interface LayerDao { */ void updateLayerMinCores(LayerInterface layer, int val); + + /** + * update the dispatch order of the layer + * + * @param layer + * @param val + */ + void updateLayerDispatchOrder(LayerInterface layer, int val); + /** * update the number of gpus the layer requires * diff --git a/cuebot/src/main/java/com/imageworks/spcue/dao/postgres/LayerDaoJdbc.java b/cuebot/src/main/java/com/imageworks/spcue/dao/postgres/LayerDaoJdbc.java index 174128ac9..0a7ac1cb7 100644 --- a/cuebot/src/main/java/com/imageworks/spcue/dao/postgres/LayerDaoJdbc.java +++ b/cuebot/src/main/java/com/imageworks/spcue/dao/postgres/LayerDaoJdbc.java @@ -313,6 +313,15 @@ public void increaseLayerMinGpuMemory(LayerInterface layer, long kb) { layer.getLayerId(), kb); } + @Override + public void updateLayerDispatchOrder(LayerInterface layer, int val) { + if (val < 0) { + throw new IllegalArgumentException("Layer dispatch order must be positive."); + } + getJdbcTemplate().update("UPDATE layer SET int_dispatch_order=? WHERE pk_layer=?", val, + layer.getLayerId()); + } + @Override public void updateLayerMinCores(LayerInterface layer, int val) { if (val < Dispatcher.CORE_POINTS_RESERVED_MIN) { diff --git a/cuebot/src/main/java/com/imageworks/spcue/servant/ManageLayer.java b/cuebot/src/main/java/com/imageworks/spcue/servant/ManageLayer.java index 0e19a2e43..d8eb96f18 100644 --- a/cuebot/src/main/java/com/imageworks/spcue/servant/ManageLayer.java +++ b/cuebot/src/main/java/com/imageworks/spcue/servant/ManageLayer.java @@ -90,6 +90,8 @@ import com.imageworks.spcue.grpc.job.LayerReorderFramesResponse; import com.imageworks.spcue.grpc.job.LayerRetryFramesRequest; import com.imageworks.spcue.grpc.job.LayerRetryFramesResponse; +import com.imageworks.spcue.grpc.job.LayerSetDispatchOrderRequest; +import com.imageworks.spcue.grpc.job.LayerSetDispatchOrderResponse; import com.imageworks.spcue.grpc.job.LayerSetMaxCoresRequest; import com.imageworks.spcue.grpc.job.LayerSetMaxCoresResponse; import com.imageworks.spcue.grpc.job.LayerSetMinCoresRequest; @@ -235,6 +237,17 @@ public void setTags(LayerSetTagsRequest request, } } + @Override + public void setDispatchOrder(LayerSetDispatchOrderRequest request, + StreamObserver responseObserver) { + updateLayer(request.getLayer()); + if (attemptChange(env, property, jobManager, layer, responseObserver)) { + jobManager.setLayerDispatchOrder(layer, request.getOrder()); + responseObserver.onNext(LayerSetDispatchOrderResponse.newBuilder().build()); + responseObserver.onCompleted(); + } + } + @Override public void setMinCores(LayerSetMinCoresRequest request, StreamObserver responseObserver) { diff --git a/cuebot/src/main/java/com/imageworks/spcue/service/JobManager.java b/cuebot/src/main/java/com/imageworks/spcue/service/JobManager.java index 4641b8e82..29d9fe213 100644 --- a/cuebot/src/main/java/com/imageworks/spcue/service/JobManager.java +++ b/cuebot/src/main/java/com/imageworks/spcue/service/JobManager.java @@ -423,6 +423,14 @@ public interface JobManager { */ List getThreadStats(LayerInterface layer); + /** + * Update the dispatch order for the given layer. + * + * @param layer + * @param order + */ + void setLayerDispatchOrder(LayerInterface layer, int order); + /** * Update the max core value for the given layer. * diff --git a/cuebot/src/main/java/com/imageworks/spcue/service/JobManagerService.java b/cuebot/src/main/java/com/imageworks/spcue/service/JobManagerService.java index 03bc765b4..49a3a40ad 100644 --- a/cuebot/src/main/java/com/imageworks/spcue/service/JobManagerService.java +++ b/cuebot/src/main/java/com/imageworks/spcue/service/JobManagerService.java @@ -441,6 +441,11 @@ public void setLayerTag(LayerInterface layer, String tag) { layerDao.updateLayerTags(layer, Sets.newHashSet(tag)); } + @Override + public void setLayerDispatchOrder(LayerInterface layer, int order) { + layerDao.updateLayerDispatchOrder(layer, order); + } + @Override public void setLayerMinCores(LayerInterface layer, int coreUnits) { layerDao.updateLayerMinCores(layer, coreUnits); diff --git a/proto/src/job.proto b/proto/src/job.proto index 4c76308fa..9b715fca3 100644 --- a/proto/src/job.proto +++ b/proto/src/job.proto @@ -358,6 +358,9 @@ service LayerInterface { // Retry the Frames of this Layer rpc RetryFrames(LayerRetryFramesRequest) returns (LayerRetryFramesResponse); + // Set the Dispatch Order of this Layer + rpc SetDispatchOrder(LayerSetDispatchOrderRequest) returns (LayerSetDispatchOrderResponse); + // The maximum number of cores to run on a given frame within this layer. Fractional core values are not allowed // with this setting. rpc SetMaxCores(LayerSetMaxCoresRequest) returns (LayerSetMaxCoresResponse); @@ -1688,6 +1691,13 @@ message LayerRetryFramesRequest { message LayerRetryFramesResponse {} // Empty +message LayerSetDispatchOrderRequest { + Layer layer = 1; + int32 order = 2; +} + +message LayerSetDispatchOrderResponse {} // Empty + // RegisterOutputPath message LayerRegisterOutputPathRequest { Layer layer = 1; diff --git a/pycue/opencue/wrappers/layer.py b/pycue/opencue/wrappers/layer.py index 8b3dfdf1b..e0e46632f 100644 --- a/pycue/opencue/wrappers/layer.py +++ b/pycue/opencue/wrappers/layer.py @@ -127,6 +127,17 @@ def setTags(self, tags): return self.stub.SetTags(job_pb2.LayerSetTagsRequest(layer=self.data, tags=tags), timeout=Cuebot.Timeout) + def setDispatchOrder(self, order): + """Sets the dispatch order for this layer. + + :type order: int + :param order: layer dipsatch order + """ + return self.stub.SetDispatchOrder( + job_pb2.LayerSetDispatchOrderRequest(layer=self.data, order=order), + timeout=Cuebot.Timeout) + + def setMaxCores(self, cores): """Sets the maximum number of cores that this layer requires. From 5a4d8114085e932d8afcbbbf0526b27dde10c3da Mon Sep 17 00:00:00 2001 From: Alexis Oblet Date: Mon, 23 Mar 2026 11:07:23 +0100 Subject: [PATCH 3/4] layer dispatch order: expose via cuegui - Allow multi selection --- cuegui/cuegui/LayerMonitorTree.py | 3 ++- cuegui/cuegui/MenuActions.py | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/cuegui/cuegui/LayerMonitorTree.py b/cuegui/cuegui/LayerMonitorTree.py index 6bb5576b2..b9e5f4d90 100644 --- a/cuegui/cuegui/LayerMonitorTree.py +++ b/cuegui/cuegui/LayerMonitorTree.py @@ -264,8 +264,9 @@ def contextMenuEvent(self, e): self.__menuActions.layers().addAction(depend_menu, "markdone") menu.addMenu(depend_menu) + menu.addSeparator() + reorder_dispatch_action = self.__menuActions.layers().addAction(menu, "reorder_dispatch") if len(__selectedObjects) == 1: - menu.addSeparator() try: if int(self.app.settings.value("DisableDeeding", 0)) == 0: if len({layer.data.range for layer in __selectedObjects}) == 1: diff --git a/cuegui/cuegui/MenuActions.py b/cuegui/cuegui/MenuActions.py index fcdae5d41..ad5630b9e 100644 --- a/cuegui/cuegui/MenuActions.py +++ b/cuegui/cuegui/MenuActions.py @@ -1076,6 +1076,31 @@ def dependWizard(self, rpcObjects=None): if layers: cuegui.DependWizard.DependWizard(self._caller, [self._getSource()], layers=layers) + + reorder_dispatch_info = ["Reorder Dispatch...", None, "configure"] + + def reorder_dispatch(self, rpcObjects=None): + layers = self._getOnlyLayerObjects(rpcObjects) + if not layers: + return + + body = "Which dispatch order to set?" + if len(layers) > 1: + title = "Reorder layers" + for layer in layers: + body += '\n%s' % layer.data.name + else: + title = "Reorder layer %s" % layer.data.name + + (order, choice) = QtWidgets.QInputDialog.getInt(self._caller, title, body, 1, 1, 100000, 1) + if not choice: + return + + for layer in layers: + self.cuebotCall(layer.setDispatchOrder, "Reorder Dispatch Failed", order) + + self._update() + reorder_info = ["Reorder Frames...", None, "configure"] def reorder(self, rpcObjects=None): From e95e7f0d32b9592adbaee9b12a90368cacc8ad8c Mon Sep 17 00:00:00 2001 From: Alexis Oblet Date: Mon, 23 Mar 2026 17:37:14 +0100 Subject: [PATCH 4/4] job proto: upgrade version for compatibility Signed-off-by: Alexis Oblet --- VERSION.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.in b/VERSION.in index d3456a90f..bc4493477 100644 --- a/VERSION.in +++ b/VERSION.in @@ -1 +1 @@ -1.13 +1.19