{"id":410,"date":"2026-07-06T22:06:03","date_gmt":"2026-07-06T20:06:03","guid":{"rendered":"https:\/\/dataguide.tech\/?p=410"},"modified":"2026-07-06T22:06:05","modified_gmt":"2026-07-06T20:06:05","slug":"fabric-custom-library-maintanance","status":"publish","type":"post","link":"https:\/\/dataguide.tech\/index.php\/2026\/07\/06\/fabric-custom-library-maintanance\/","title":{"rendered":"How to Maintain Custom Libraries Across Fabric Workspaces"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">If you&#8217;ve been building shared code for your team in Fabric, you already know the easy part is writing the library. The hard part shows up later: keeping that same library consistent across a dozen workspaces without turning every release into a manual chore.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I&#8217;ve covered how to <a href=\"https:\/\/dataguide.tech\/index.php\/2026\/02\/24\/custom-environment-whats-that-what-is-the-reason\/\">work as a team in an enterprise way<\/a> and how to <a href=\"https:\/\/dataguide.tech\/index.php\/2026\/04\/30\/build-fabric-notebooks-library\/\">build your own library for Fabric<\/a> in earlier posts. This one picks up where those left off &#8211; how do you actually maintain those libraries once they&#8217;re spread across your tenant?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are two strategies I lean on, and I switch between them depending on the setup. Neither is &#8220;the right one&#8221; &#8211; they solve slightly different problems.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Two Ways to Manage Libraries Across Workspaces<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Before we get into the wiring, here&#8217;s the short version of both approaches:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>One shared environment<\/strong> &#8211; you create an environment in a central workspace and point notebooks from other workspaces at it. Update it once, everyone gets the change.<\/li>\n\n\n\n<li><strong>One shared library, many environments<\/strong> &#8211; you keep the <code>.whl<\/code> in a single place and use a script to push it out to environments living in each workspace. More moving parts, but far more flexible on the compute side.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s take each one in turn.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Architecture 1: A Single Shared Environment<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This is the simpler of the two, and honestly it&#8217;s where I&#8217;d start most teams.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You spin up a workspace that holds shareable items, and one of those items is a shareable environment (or a few of them, if you have different workload profiles). Because everything points back to one place, maintenance is painless &#8211; any update to the environment happens in a single spot, and every notebook connected to it immediately picks up the new Spark cluster, library, or resource.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The trade-off is configurability. If you want a cluster defined independently <em>while<\/em> reusing the same shared library, this isn&#8217;t the way to go &#8211; that&#8217;s exactly the gap the second architecture fills. But if you&#8217;re after simplicity and a single org-wide standard, this gets you there fast.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture with a single shared environment<\/strong><br>\n<img decoding=\"async\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260525193245.png\" alt=\"Pasted image 20260525193245.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can see it in the diagram above: multiple notebooks all pointing at the same shared workspace, which holds the shared library the developers use. Wiring a notebook to it takes two clicks:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the notebook.<\/li>\n\n\n\n<li>Expand the environment list and pick the shared environment. That&#8217;s it &#8211; your custom libraries from that environment are now available.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"894\" height=\"745\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260531114732-1.png\" alt=\"Pasted image 20260531114732.png\" class=\"wp-image-420\" srcset=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260531114732-1.png 894w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260531114732-1-300x250.png 300w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260531114732-1-768x640.png 768w\" sizes=\"auto, (max-width: 894px) 100vw, 894px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There&#8217;s a natural extension here. Instead of one shared environment, create a few &#8211; one per workload type. Small jobs get a lightweight Spark config, heavy loads get something beefier. The setup is identical; the only difference is that your shared workspace now holds more than one environment. Pick whichever one matches the job.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Architecture 2: One Library, Pushed to Every Workspace<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The second approach is the one I reach for on larger tenants. You still want reusable code sitting in one place, and you still want every workload running the latest version &#8211; but now you also want full control over each environment&#8217;s Spark engine and resources. A single shared environment can&#8217;t give you both.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1256\" height=\"734\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260627135418-1.png\" alt=\"Pasted image 20260627135418.png\" class=\"wp-image-419\" srcset=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260627135418-1.png 1256w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260627135418-1-300x175.png 300w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260627135418-1-1024x598.png 1024w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260627135418-1-768x449.png 768w\" sizes=\"auto, (max-width: 1256px) 100vw, 1256px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the idea. On a shared workspace you store the <code>.whl<\/code> library file (add versioning here if you like), plus a script that publishes it out to environments in other workspaces. You decide which environments are in scope. In my sample script I push it across the whole tenant &#8211; personal workspaces excluded &#8211; wherever I find an environment with a <code>DE<\/code> suffix.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let me walk through the setup.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, create the target environments in your workspaces using a consistent naming convention. I use a <code>DE<\/code> suffix. You can use your own rule, but heads up &#8211; the script matches on <code>_DE<\/code>, so if you change the convention you&#8217;ll need to adjust it to match.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"538\" height=\"770\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140443-1.png\" alt=\"Pasted image 20260704140443.png\" class=\"wp-image-421\" srcset=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140443-1.png 538w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140443-1-210x300.png 210w\" sizes=\"auto, (max-width: 538px) 100vw, 538px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Next, create a notebook in your &#8220;shared tool&#8221; workspace. It can technically live anywhere, but I keep all reusable items in one workspace so the team always knows where to look. Once the notebook exists, attach your library to it as a built-in resource:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Open the notebook \u2192 go to the <strong>Resources<\/strong> tab in the explorer \u2192 click the three dots next to <strong>Built-in<\/strong> \u2192 click <strong>Upload files<\/strong> \u2192 select your library.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1540\" height=\"896\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140738-1.png\" alt=\"Pasted image 20260704140738.png\" class=\"wp-image-417\" srcset=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140738-1.png 1540w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140738-1-300x175.png 300w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140738-1-1024x596.png 1024w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140738-1-768x447.png 768w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704140738-1-1536x894.png 1536w\" sizes=\"auto, (max-width: 1540px) 100vw, 1540px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">With the prerequisites in place, here&#8217;s the script <em>(This scripts exists as well in my GH Repo &#8211; <a href=\"https:\/\/github.com\/LukaszLubinaDataGuide\/DataGuide-Blog\/tree\/main\/Custom_Library_Deployment\" target=\"_blank\" rel=\"noopener\">Github<\/a><\/em>):<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#a6accd;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#252937;color:#969dc4\">Python<\/span><span role=\"button\" tabindex=\"0\" style=\"color:#a6accd;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly># ---- 0. Import libraries ----------------------------------------------\nimport re\nimport requests\nimport notebookutils\n\n# ---- 1. Parameters ----------------------------------------------------\nWHL_NAME = \"dataguide_demolibrary-0.2.0-py3-none-any.whl\"  # new version, sitting in notebook Resources\nENV_PATTERN = \"_DE\"  # match environments named *_DE (suffix match)\n\n# ---- 2. Setup ---------------------------------------------------------\nBASE = \"https:\/\/api.fabric.microsoft.com\/v1\"\nTOKEN = notebookutils.credentials.getToken(\"pbi\")  # token for the current user, no service principal needed\nH = {\"Authorization\": f\"Bearer {TOKEN}\"}\n\nwhl_path = f\"{notebookutils.nbResPath}\/builtin\/{WHL_NAME}\"\nwhl_bytes = open(whl_path, \"rb\").read()\npackage = re.split(r\"&#91;-_&#93;\\d\", WHL_NAME)&#91;0&#93;  # \"my_library\" -> used to find &amp; remove old versions\nprint(f\"Wheel: {WHL_NAME} ({len(whl_bytes)\/1024:.0f} KB) package='{package}'\")\n\n# ---- 3. Helpers -------------------------------------------------------\ndef get_all(url):\n    \"\"\"GET a Fabric list endpoint, following pagination.\"\"\"\n    items = []\n    while url:\n        r = requests.get(url, headers=H); r.raise_for_status()\n        body = r.json()\n        items += body.get(\"value\", [])\n        url = body.get(\"continuationUri\")\n    return items\n\ndef deploy(ws_id, env_id):\n    libs = f\"{BASE}\/workspaces\/{ws_id}\/environments\/{env_id}\/staging\/libraries\"\n    # 3a. remove any existing version of the same package\n    existing = requests.get(f\"{libs}?beta=false\", headers=H).json().get(\"libraries\", [])\n    for lib in existing:\n        name = lib.get(\"name\", \"\")\n        if (lib.get(\"libraryType\") == \"Custom\" and name.endswith(\".whl\")\n                and re.split(r\"&#91;-_&#93;\\d\", name)&#91;0&#93; == package):\n            requests.delete(f\"{libs}\/{name}\", headers=H).raise_for_status()\n    # 3b. upload the new wheel\n    up = requests.post(f\"{libs}\/{WHL_NAME}\",\n                       headers={**H, \"Content-Type\": \"application\/octet-stream\"},\n                       data=whl_bytes)\n    up.raise_for_status()\n    # 3c. publish so attached notebooks pick up the change\n    requests.post(f\"{BASE}\/workspaces\/{ws_id}\/environments\/{env_id}\/staging\/publish\",\n                  headers=H).raise_for_status()\n\n# ---- 4. Scan every workspace, deploy to each *_DE environment ---------\nupdated = []\nfor ws in get_all(f\"{BASE}\/workspaces\"):\n    try:\n        envs = get_all(f\"{BASE}\/workspaces\/{ws&#91;'id'&#93;}\/environments\")\n    except Exception:\n        continue  # skip workspaces that don't expose environments\n    for env in envs:\n        if env&#91;\"displayName\"&#93;.endswith(ENV_PATTERN):\n            try:\n                deploy(ws&#91;\"id\"&#93;, env&#91;\"id\"&#93;)\n                updated.append(ws&#91;\"displayName\"&#93;)\n            except Exception as e:\n                print(f\" ! Failed in {ws&#91;'displayName'&#93;} \/ {env&#91;'displayName'&#93;}: {e}\")\n\n# ---- 5. Report --------------------------------------------------------\nprint(f\"\\nUpdated {WHL_NAME} in {len(updated)} workspace(s):\")\nfor name in sorted(updated):\n    print(f\" - {name}\")\nprint(\"\\nPublish runs in the background (typically a few minutes per environment).\")\n<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6\"><\/path><\/svg><\/span><pre class=\"shiki poimandres\" style=\"background-color: #1b1e28\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #767C9DB0; font-style: italic\"># ---- 0. Import libraries ----------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #5DE4C7\">import<\/span><span style=\"color: #A6ACCD\"> re<\/span><\/span>\n<span class=\"line\"><span style=\"color: #5DE4C7\">import<\/span><span style=\"color: #A6ACCD\"> requests<\/span><\/span>\n<span class=\"line\"><span style=\"color: #5DE4C7\">import<\/span><span style=\"color: #A6ACCD\"> notebookutils<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #767C9DB0; font-style: italic\"># ---- 1. Parameters ----------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">WHL_NAME <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">dataguide_demolibrary-0.2.0-py3-none-any.whl<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">  <\/span><span style=\"color: #767C9DB0; font-style: italic\"># new version, sitting in notebook Resources<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">ENV_PATTERN <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">_DE<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">  <\/span><span style=\"color: #767C9DB0; font-style: italic\"># match environments named *_DE (suffix match)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #767C9DB0; font-style: italic\"># ---- 2. Setup ---------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">BASE <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">https:\/\/api.fabric.microsoft.com\/v1<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">TOKEN <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> notebookutils.credentials.getToken(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">pbi<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">)  <\/span><span style=\"color: #767C9DB0; font-style: italic\"># token for the current user, no service principal needed<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">H <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> {<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">Authorization<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">: <\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;Bearer <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">TOKEN<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #A6ACCD\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">whl_path <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">notebookutils.nbResPath<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/builtin\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">WHL_NAME<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">whl_bytes <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #E4F0FBD0\">open<\/span><span style=\"color: #A6ACCD\">(whl_path, <\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">rb<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">).read()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">package <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> re.split(<\/span><span style=\"color: #91B4D5\">r<\/span><span style=\"color: #A6ACCD\">&quot;&#91;<\/span><span style=\"color: #5DE4C7\">-_<\/span><span style=\"color: #A6ACCD\">&#93;<\/span><span style=\"color: #5FB3A1\">\\d<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">, WHL_NAME)&#91;<\/span><span style=\"color: #5DE4C7\">0<\/span><span style=\"color: #A6ACCD\">&#93;  <\/span><span style=\"color: #767C9DB0; font-style: italic\"># &quot;my_library&quot; -&gt; used to find &amp; remove old versions<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E4F0FBD0\">print<\/span><span style=\"color: #A6ACCD\">(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;Wheel: <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">WHL_NAME<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\"> (<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #E4F0FBD0\">len<\/span><span style=\"color: #A6ACCD\">(whl_bytes)<\/span><span style=\"color: #91B4D5\">\/<\/span><span style=\"color: #5DE4C7\">1024<\/span><span style=\"color: #91B4D5\">:.0f<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\"> KB) package=&#39;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">package<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">&#39;&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #767C9DB0; font-style: italic\"># ---- 3. Helpers -------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #91B4D5\">def<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #ADD7FF\">get_all<\/span><span style=\"color: #A6ACCD\">(<\/span><span style=\"color: #E4F0FB\">url<\/span><span style=\"color: #A6ACCD\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #A6ACCD\">&quot;&quot;&quot;<\/span><span style=\"color: #5DE4C7\">GET a Fabric list endpoint, following pagination.<\/span><span style=\"color: #A6ACCD\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    items <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #5DE4C7C0\">while<\/span><span style=\"color: #A6ACCD\"> url:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        r <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> requests.get(url, <\/span><span style=\"color: #E4F0FB\">headers<\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\">H); r.raise_for_status()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        body <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> r.json()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        items <\/span><span style=\"color: #91B4D5\">+=<\/span><span style=\"color: #A6ACCD\"> body.get(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">value<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">, [])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        url <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> body.get(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">continuationUri<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #5DE4C7C0\">return<\/span><span style=\"color: #A6ACCD\"> items<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #91B4D5\">def<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #ADD7FF\">deploy<\/span><span style=\"color: #A6ACCD\">(<\/span><span style=\"color: #E4F0FB\">ws_id<\/span><span style=\"color: #A6ACCD\">, <\/span><span style=\"color: #E4F0FB\">env_id<\/span><span style=\"color: #A6ACCD\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    libs <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">BASE<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/workspaces\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">ws_id<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/environments\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">env_id<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/staging\/libraries&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #767C9DB0; font-style: italic\"># 3a. remove any existing version of the same package<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    existing <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> requests.get(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">libs<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">?beta=false&quot;<\/span><span style=\"color: #A6ACCD\">, <\/span><span style=\"color: #E4F0FB\">headers<\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\">H).json().get(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">libraries<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">, [])<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #5DE4C7C0\">for<\/span><span style=\"color: #A6ACCD\"> lib <\/span><span style=\"color: #5DE4C7C0\">in<\/span><span style=\"color: #A6ACCD\"> existing:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        name <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> lib.get(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">name<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">, <\/span><span style=\"color: #A6ACCD\">&quot;&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        <\/span><span style=\"color: #5DE4C7C0\">if<\/span><span style=\"color: #A6ACCD\"> (lib.get(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">libraryType<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">) <\/span><span style=\"color: #91B4D5\">==<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">Custom<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #91B4D5\">and<\/span><span style=\"color: #A6ACCD\"> name.endswith(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">.whl<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">                <\/span><span style=\"color: #91B4D5\">and<\/span><span style=\"color: #A6ACCD\"> re.split(<\/span><span style=\"color: #91B4D5\">r<\/span><span style=\"color: #A6ACCD\">&quot;&#91;<\/span><span style=\"color: #5DE4C7\">-_<\/span><span style=\"color: #A6ACCD\">&#93;<\/span><span style=\"color: #5FB3A1\">\\d<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">, name)&#91;<\/span><span style=\"color: #5DE4C7\">0<\/span><span style=\"color: #A6ACCD\">&#93; <\/span><span style=\"color: #91B4D5\">==<\/span><span style=\"color: #A6ACCD\"> package):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">            requests.delete(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">libs<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">name<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #A6ACCD\">, <\/span><span style=\"color: #E4F0FB\">headers<\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\">H).raise_for_status()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #767C9DB0; font-style: italic\"># 3b. upload the new wheel<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    up <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> requests.post(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">libs<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">WHL_NAME<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #A6ACCD\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">                       <\/span><span style=\"color: #E4F0FB\">headers<\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\">{<\/span><span style=\"color: #91B4D5\">**<\/span><span style=\"color: #A6ACCD\">H, <\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">Content-Type<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">: <\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">application\/octet-stream<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">},<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">                       <\/span><span style=\"color: #E4F0FB\">data<\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\">whl_bytes)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    up.raise_for_status()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #767C9DB0; font-style: italic\"># 3c. publish so attached notebooks pick up the change<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    requests.post(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">BASE<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/workspaces\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">ws_id<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/environments\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">env_id<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/staging\/publish&quot;<\/span><span style=\"color: #A6ACCD\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">                  <\/span><span style=\"color: #E4F0FB\">headers<\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\">H).raise_for_status()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #767C9DB0; font-style: italic\"># ---- 4. Scan every workspace, deploy to each *_DE environment ---------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">updated <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #5DE4C7C0\">for<\/span><span style=\"color: #A6ACCD\"> ws <\/span><span style=\"color: #5DE4C7C0\">in<\/span><span style=\"color: #A6ACCD\"> get_all(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">BASE<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/workspaces&quot;<\/span><span style=\"color: #A6ACCD\">):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #5DE4C7C0\">try<\/span><span style=\"color: #A6ACCD\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        envs <\/span><span style=\"color: #91B4D5\">=<\/span><span style=\"color: #A6ACCD\"> get_all(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">BASE<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/workspaces\/<\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">ws&#91;<\/span><span style=\"color: #A6ACCD\">&#39;<\/span><span style=\"color: #5DE4C7\">id<\/span><span style=\"color: #A6ACCD\">&#39;<\/span><span style=\"color: #A6ACCD\">&#93;<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">\/environments&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #5DE4C7C0\">except<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #A6ACCDC0\">Exception<\/span><span style=\"color: #A6ACCD\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        <\/span><span style=\"color: #5DE4C7C0\">continue<\/span><span style=\"color: #A6ACCD\">  <\/span><span style=\"color: #767C9DB0; font-style: italic\"># skip workspaces that don&#39;t expose environments<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #5DE4C7C0\">for<\/span><span style=\"color: #A6ACCD\"> env <\/span><span style=\"color: #5DE4C7C0\">in<\/span><span style=\"color: #A6ACCD\"> envs:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">        <\/span><span style=\"color: #5DE4C7C0\">if<\/span><span style=\"color: #A6ACCD\"> env&#91;<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">displayName<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">&#93;.endswith(ENV_PATTERN):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">            <\/span><span style=\"color: #5DE4C7C0\">try<\/span><span style=\"color: #A6ACCD\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">                deploy(ws&#91;<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">id<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">&#93;, env&#91;<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">id<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">                updated.append(ws&#91;<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5DE4C7\">displayName<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">&#93;)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">            <\/span><span style=\"color: #5DE4C7C0\">except<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #A6ACCDC0\">Exception<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #5DE4C7C0\">as<\/span><span style=\"color: #A6ACCD\"> e:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">                <\/span><span style=\"color: #E4F0FBD0\">print<\/span><span style=\"color: #A6ACCD\">(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot; ! Failed in <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">ws&#91;<\/span><span style=\"color: #A6ACCD\">&#39;<\/span><span style=\"color: #5DE4C7\">displayName<\/span><span style=\"color: #A6ACCD\">&#39;<\/span><span style=\"color: #A6ACCD\">&#93;<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\"> \/ <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">env&#91;<\/span><span style=\"color: #A6ACCD\">&#39;<\/span><span style=\"color: #5DE4C7\">displayName<\/span><span style=\"color: #A6ACCD\">&#39;<\/span><span style=\"color: #A6ACCD\">&#93;<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">: <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">e<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #767C9DB0; font-style: italic\"># ---- 5. Report --------------------------------------------------------<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E4F0FBD0\">print<\/span><span style=\"color: #A6ACCD\">(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #5FB3A1\">\\n<\/span><span style=\"color: #5DE4C7\">Updated <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">WHL_NAME<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\"> in <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #E4F0FBD0\">len<\/span><span style=\"color: #A6ACCD\">(updated)<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\"> workspace(s):&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #5DE4C7C0\">for<\/span><span style=\"color: #A6ACCD\"> name <\/span><span style=\"color: #5DE4C7C0\">in<\/span><span style=\"color: #A6ACCD\"> <\/span><span style=\"color: #E4F0FBD0\">sorted<\/span><span style=\"color: #A6ACCD\">(updated):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #A6ACCD\">    <\/span><span style=\"color: #E4F0FBD0\">print<\/span><span style=\"color: #A6ACCD\">(<\/span><span style=\"color: #91B4D5\">f<\/span><span style=\"color: #5DE4C7\">&quot; - <\/span><span style=\"color: #5DE4C7\">{<\/span><span style=\"color: #A6ACCD\">name<\/span><span style=\"color: #5DE4C7\">}<\/span><span style=\"color: #5DE4C7\">&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #E4F0FBD0\">print<\/span><span style=\"color: #A6ACCD\">(<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #5FB3A1\">\\n<\/span><span style=\"color: #5DE4C7\">Publish runs in the background (typically a few minutes per environment).<\/span><span style=\"color: #A6ACCD\">&quot;<\/span><span style=\"color: #A6ACCD\">)<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Run it, and you get a printed list of the workspaces the library landed in. It finishes fast &#8211; all it does is upload and kick off the publish. The publish itself runs in the background, so the script never sits there waiting on it.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1744\" height=\"426\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704141343-1.png\" alt=\"Pasted image 20260704141343.png\" class=\"wp-image-416\" srcset=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704141343-1.png 1744w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704141343-1-300x73.png 300w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704141343-1-1024x250.png 1024w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704141343-1-768x188.png 768w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704141343-1-1536x375.png 1536w\" sizes=\"auto, (max-width: 1744px) 100vw, 1744px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"799\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143024-scaled-1.png\" alt=\"Pasted image 20260704143024.png\" class=\"wp-image-418\" srcset=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143024-scaled-1.png 2560w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143024-scaled-1-300x94.png 300w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143024-scaled-1-1024x320.png 1024w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143024-scaled-1-768x240.png 768w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143024-scaled-1-1536x479.png 1536w, https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143024-scaled-1-2048x639.png 2048w\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" \/><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">Updating to a New Version<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The same script handles version bumps &#8211; no second script to maintain. After you update the library, just run it again. It looks for the package by name (the part before the version, which is why a consistent naming convention matters), finds it in the environments that are in scope, removes the old one, and uploads the new build. Publish happens in the background here too.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Upload the new version and update the variable<\/strong><br>\n<img decoding=\"async\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143327.png\" alt=\"Pasted image 20260704143327.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Run the script<\/strong><br>\n<img decoding=\"async\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143538.png\" alt=\"Pasted image 20260704143538.png\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Check the results<\/strong><br>\n<img decoding=\"async\" src=\"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Pasted-image-20260704143519-scaled.png\" alt=\"Pasted image 20260704143519.png\"><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Wrapping Up<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s the two approaches I use for keeping custom libraries consistent across a Fabric tenant. One shared environment when you want simplicity and a single standard. One shared library pushed to many environments when you need the reusable code centralized but the compute flexible per workspace.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Which one fits your day-to-day? Or are you handling this some other way entirely? Drop it in the comments &#8211; always curious how other teams tackle this.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Happy automating!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve been building shared code for your team in Fabric, you already know the easy part is writing the library. The hard part shows up later: keeping that same library consistent across a dozen workspaces without turning every release into a manual chore. I&#8217;ve covered how to work as a team in an enterprise&#8230;<\/p>\n","protected":false},"author":1,"featured_media":414,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_kadence_starter_templates_imported_post":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[9,8],"tags":[11,13,10],"class_list":["post-410","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-fabric","category-administration","tag-administration","tag-fabric","tag-microsoftfabric"],"jetpack_featured_media_url":"https:\/\/dataguide.tech\/wp-content\/uploads\/2026\/07\/Library-Deployment-picture.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/posts\/410","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/comments?post=410"}],"version-history":[{"count":3,"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/posts\/410\/revisions"}],"predecessor-version":[{"id":422,"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/posts\/410\/revisions\/422"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/media\/414"}],"wp:attachment":[{"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/media?parent=410"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/categories?post=410"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dataguide.tech\/index.php\/wp-json\/wp\/v2\/tags?post=410"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}