{"product":"edge-apps-actions","releases":[{"date":"2026-10-26","entries":[{"areas":["developers"],"breaking":false,"content_html":"\u003cp\u003eUntil this release, every Edge App repo carried its own full copy of the example workflows: the\ntriggers, the jobs for each environment, the production tag check, and the id expressions. Now those\nlive in this repo as reusable workflows, and an app\u0026rsquo;s workflow file calls them:\u003c/p\u003e\n\u003cdiv class=\"code-block\"\u003e\n  \u003cbutton type=\"button\" class=\"code-copy\" aria-label=\"Copy code\" data-copy-code\u003e\n    \u003csvg data-copy viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\u003e\n      \u003crect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\"\u003e\u003c/rect\u003e\n      \u003cpath d=\"M5 15V5a2 2 0 0 1 2-2h10\"\u003e\u003c/path\u003e\n    \u003c/svg\u003e\n    \u003csvg data-check viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"\u003e\n      \u003cpath d=\"M20 6 9 17l-5-5\"\u003e\u003c/path\u003e\n    \u003c/svg\u003e\n  \u003c/button\u003e\n  \u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-yaml\" data-lang=\"yaml\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003ename\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e \u003c/span\u003eUpdate Edge App\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003eon\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e  \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003eworkflow_dispatch\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e  \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003epush\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e    \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003ebranches\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e \u003c/span\u003e[main, master]\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e    \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003etags\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e \u003c/span\u003e[\u003cspan style=\"color:#ed9d13\"\u003e\u0026#39;v[0-9]*\u0026#39;\u003c/span\u003e]\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003epermissions\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e  \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003econtents\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e \u003c/span\u003eread\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003ejobs\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e  \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003eupdate\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e    \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003euses\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e \u003c/span\u003eScreenly/edge-apps-actions/.github/workflows/update.yml@v26.10.2\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e    \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003esecrets\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#666\"\u003e      \u003c/span\u003e\u003cspan style=\"color:#6ab825;font-weight:bold\"\u003eSCREENLY_API_TOKEN\u003c/span\u003e:\u003cspan style=\"color:#666\"\u003e \u003c/span\u003e${{ secrets.SCREENLY_API_TOKEN }}\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eWhen a later release changes how deploys work, bumping that pin is all it takes. Copy the 3 files in\n\u003ccode\u003eexamples/\u003c/code\u003e into your app\u0026rsquo;s \u003ccode\u003e.github/workflows/\u003c/code\u003e to start.\u003c/p\u003e\n\u003ctable\u003e\n\t\u003cthead\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003cth\u003eWorkflow\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003eInputs\u003c/th\u003e\n\t\t\t\t\t\u003cth\u003eSecrets\u003c/th\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/thead\u003e\n\t\u003ctbody\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003echecks.yml\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003ebun-version\u003c/code\u003e (default \u003ccode\u003elatest\u003c/code\u003e)\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003enone\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003einitialize.yml\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003eenvironment\u003c/code\u003e, \u003ccode\u003eedge_app_name\u003c/code\u003e, \u003ccode\u003eedge_app_title\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003eSCREENLY_API_TOKEN\u003c/code\u003e\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\t\t\u003ctr\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003eupdate.yml\u003c/code\u003e\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003edelete_missing_settings\u003c/code\u003e (default \u003ccode\u003etrue\u003c/code\u003e)\u003c/td\u003e\n\t\t\t\t\t\u003ctd\u003e\u003ccode\u003eSCREENLY_API_TOKEN\u003c/code\u003e\u003c/td\u003e\n\t\t\t\u003c/tr\u003e\n\t\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e\u003ccode\u003eupdate.yml\u003c/code\u003e deploys to stage on a push or a manual run on the default branch, and other branches\nnever deploy. It deploys to production when you push a \u003ccode\u003ev*\u003c/code\u003e tag whose commit is on the default\nbranch, through the \u003ccode\u003eproduction\u003c/code\u003e environment and its reviewers. \u003ccode\u003echecks.yml\u003c/code\u003e cancels a check still\nrunning on a branch when a newer push to that branch arrives.\u003c/p\u003e\n\u003ch2 id=\"setting-up-an-app\"\u003eSetting up an app\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eCreate the GitHub environments \u003ccode\u003estage\u003c/code\u003e and \u003ccode\u003eproduction\u003c/code\u003e, and add \u003ccode\u003eSCREENLY_API_TOKEN\u003c/code\u003e to each as\nan environment secret. An environment secret only reaches jobs that run in that environment, so\nthe production token stays behind production\u0026rsquo;s reviewers.\u003c/li\u003e\n\u003cli\u003eRun \u0026ldquo;Initialize Edge App\u0026rdquo; for \u003ccode\u003estage\u003c/code\u003e. Once the run has finished successfully, set the repository\nvariable \u003ccode\u003eSTAGE_EDGE_APP_ID\u003c/code\u003e to the id in its job summary. Setting it earlier lets a deploy start\nwhile Initialize is still running.\u003c/li\u003e\n\u003cli\u003eDo the same for \u003ccode\u003eproduction\u003c/code\u003e and \u003ccode\u003ePRODUCTION_EDGE_APP_ID\u003c/code\u003e.\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003ccode\u003edelete_missing_settings\u003c/code\u003e is \u003ccode\u003etrue\u003c/code\u003e in \u003ccode\u003eupdate.yml\u003c/code\u003e, so the manifest decides which settings exist.\nThe \u003ccode\u003eupdate\u003c/code\u003e action on its own still defaults to \u003ccode\u003efalse\u003c/code\u003e. To keep settings that aren\u0026rsquo;t in your\nmanifest, pass \u003ccode\u003edelete_missing_settings: false\u003c/code\u003e under \u003ccode\u003ewith:\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eThe \u003ccode\u003echecks\u003c/code\u003e, \u003ccode\u003einitialize\u003c/code\u003e, and \u003ccode\u003eupdate\u003c/code\u003e actions are still there to use as steps in a workflow of\nyour own.\u003c/p\u003e\n","description":"Reusable checks, initialize, and update workflows hold the whole deploy setup, so an Edge App repo's workflow files only pin a version and pass SCREENLY_API_TOKEN.","title":"Checks, initialize, and update now come as reusable workflows","type":"release","url":"https://www.screenly.io/releases/edge-apps-actions/26.10.2/reusable-workflows/"},{"areas":["developers"],"breaking":false,"content_html":"\u003cp\u003eMerge 3 pull requests into \u003ccode\u003emain\u003c/code\u003e in a row, and the update workflow deploys the first to stage while\nthe second waits. When the third arrives, it takes the second\u0026rsquo;s place in line. Stage ends up on the\nnewest commit after 2 deploys, and a running deploy is never cancelled to get there.\u003c/p\u003e\n\u003cp\u003eProduction tags queue the same way, separately from stage. If an older production run is still\nwaiting for a reviewer, reject it so the newest one goes next.\u003c/p\u003e\n\u003cp\u003eInitialize has a queue of its own, so a push can\u0026rsquo;t take the place of an Initialize run that\u0026rsquo;s\nwaiting.\u003c/p\u003e\n\u003cp\u003eTo redo a failed or cancelled production deploy, re-run that tag\u0026rsquo;s workflow run. You don\u0026rsquo;t need a\nnew tag. If the earlier run stopped part-way, the re-run can report success while the app stays on\nits previous revision, so check the live revision in Screenly afterward. If it didn\u0026rsquo;t move, push a\nnew tag with a change to the app\u0026rsquo;s files.\u003c/p\u003e\n","description":"The update workflow runs 1 deploy per environment, keeps only the newest waiting run, and never cancels a deploy that's already running.","title":"Deploys to an environment run one at a time","type":"improvement","url":"https://www.screenly.io/releases/edge-apps-actions/26.10.2/deploys-run-one-at-a-time/"},{"areas":[],"breaking":false,"content_html":"\u003ch2 id=\"fixes\"\u003eFixes\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eIf \u003ccode\u003epackage.json\u003c/code\u003e can\u0026rsquo;t be parsed, \u003ccode\u003einitialize\u003c/code\u003e and \u003ccode\u003eupdate\u003c/code\u003e stop with an error instead of\ndeploying the repo root.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"improvements\"\u003eImprovements\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003einitialize\u003c/code\u003e stops if an Edge App with the same name already exists in that environment, so\nrunning it twice can\u0026rsquo;t create 2 apps. If it can\u0026rsquo;t get the list of Edge Apps to check, it stops\nwithout creating anything.\u003c/li\u003e\n\u003c/ul\u003e\n","description":"initialize stops if an Edge App with the same name already exists, and both actions stop with an error when package.json can't be parsed.","title":"The initialize action won't create the same app twice, and other fixes","type":"roundup","url":"https://www.screenly.io/releases/edge-apps-actions/26.10.2/fixes-and-improvements/"}],"json":"https://www.screenly.io/releases/edge-apps-actions/26.10.2/v1.json","product":"edge-apps-actions","product_label":"Edge Apps GitHub Actions","url":"https://www.screenly.io/releases/edge-apps-actions/26.10.2/","version":"26.10.2"}],"title":"Edge Apps GitHub Actions 26.10.2","url":"https://www.screenly.io/releases/edge-apps-actions/26.10.2/","version":1}