Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
489d16d
chore(deps): bump @screenly/edge-apps to 1.2.1 (#29)
nicomiguelino Jul 23, 2026
828f1c8
Use EDGE_APP_ID for stage and production deploys (#36)
nicomiguelino Sep 4, 2026
b62ffc3
fix: restore screenly_qc.yml, still used by the custom RSS reader wor…
nicomiguelino Sep 4, 2026
69b2efb
Merge branch 'main' into development
salmanfarisvp Sep 16, 2026
b6d89ea
ci: use edge-apps-actions v26.10.0 with CalVer tag releases
salmanfarisvp Oct 21, 2026
fc118c2
docs: add release badge and preview screenshot to README
salmanfarisvp Oct 21, 2026
419f7bb
docs: document the tag-based release process in README
salmanfarisvp Oct 21, 2026
66eabf9
ci: run checks on the development branch
salmanfarisvp Oct 21, 2026
a672403
ci: call edge-apps-actions v26.10.2 reusable workflows
salmanfarisvp Oct 28, 2026
2a99668
Merge pull request #43 from Screenly/chore/edge-apps-actions-v26.10.0
salmanfarisvp Oct 29, 2026
8f04403
Merge main into development
salmanfarisvp Oct 29, 2026
0a236a7
ci: only deploy feed apps to production from tags on main
salmanfarisvp Oct 29, 2026
de29a12
Merge pull request #47 from Screenly/ci/feed-apps-tag-check
salmanfarisvp Oct 29, 2026
0f7cc71
Merge pull request #45 from Screenly/sync/default-into-development
salmanfarisvp Oct 29, 2026
ebcdb07
feat: redesign the reader as a news board
lucasclgibson Aug 19, 2026
859b167
ci: run checks on the development branch
lucasclgibson Aug 19, 2026
7a2d41c
Merge remote-tracking branch 'origin/development' into feat/redesign-…
lucasclgibson Oct 31, 2026
7332d91
fix: request screen-sized BBC images instead of 240px thumbnails
salmanfarisvp Nov 3, 2026
f82942d
fix: stop the lead story clipping lines in landscape
salmanfarisvp Nov 3, 2026
84adfbb
ci: address Copilot review feedback on the release workflows
salmanfarisvp Nov 3, 2026
2f1c7f5
Merge pull request #33 from Screenly/feat/redesign-rss-reader
salmanfarisvp Nov 3, 2026
f59a0f9
fix: resize every BBC image URL shape and document the mode setting
salmanfarisvp Nov 4, 2026
3f46e0e
Merge pull request #48 from Screenly/fix/release-workflow-feedback
salmanfarisvp Nov 4, 2026
ed4ac4e
ci: deploy feed apps through the shared edge-apps-actions
salmanfarisvp Nov 4, 2026
e972b97
Merge pull request #49 from Screenly/fix/copilot-redesign-feedback
salmanfarisvp Nov 4, 2026
1b1a086
fix: remove the duplicate apps key from deployed-apps.yml
salmanfarisvp Nov 4, 2026
b37e81b
docs: document releases, publishing and updating feed apps in the README
salmanfarisvp Nov 4, 2026
aeda7e3
Merge pull request #50 from Screenly/ci/feed-apps-shared-actions
salmanfarisvp Nov 4, 2026
39345f2
Merge pull request #51 from Screenly/docs/release-and-feed-apps
salmanfarisvp Nov 4, 2026
ce0de44
fix: tie the feed cache to its feed and expire it, clamp cache_interval
salmanfarisvp Nov 5, 2026
66ca21a
fix: validate cached entries and prune before saving the cache
salmanfarisvp Nov 5, 2026
b3de3bf
fix: treat a cache saved in the future as stale
salmanfarisvp Nov 5, 2026
ed4bc3f
Merge pull request #52 from Screenly/fix/feed-cache
salmanfarisvp Nov 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions .github/actions/apply-feed-app/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
name: Apply feed app config
description: >
Turns screenly.yml into the manifest for one feed app from deployed-apps.yml,
so the shared edge-apps-actions can deploy it like any other Edge App. The
code is the same for every feed app; only these manifest fields differ.

inputs:
app_key:
description: Key of the app under `apps:` in deployed-apps.yml (e.g. bbc-news)
required: true
environment:
description: stage or production, to look up the app's id for it
required: true
override_description:
description: Use instead of the app's description (optional)
required: false
default: ''
override_icon_url:
description: Use instead of the app's icon_url (optional)
required: false
default: ''
override_rss_title:
description: Use instead of the app's rss_title (optional)
required: false
default: ''
override_rss_url:
description: Use instead of the app's rss_url (optional)
required: false
default: ''

outputs:
app_name:
description: The app's app_name, used as the Edge App name and instance title
value: ${{ steps.apply.outputs.app_name }}
edge_app_id:
description: The app's id for this environment, or empty if it has none yet
value: ${{ steps.apply.outputs.edge_app_id }}

runs:
using: composite
steps:
- name: Setup yq
uses: ./.github/actions/setup-yq

- name: Apply ${{ inputs.app_key }} to screenly.yml
id: apply
shell: bash
# Inputs arrive as environment variables, never pasted into the script,
# so quotes or $ in a description can't break the step
env:
APP_KEY: ${{ inputs.app_key }}
ENVIRONMENT: ${{ inputs.environment }}
OVERRIDE_DESCRIPTION: ${{ inputs.override_description }}
OVERRIDE_ICON_URL: ${{ inputs.override_icon_url }}
OVERRIDE_RSS_TITLE: ${{ inputs.override_rss_title }}
OVERRIDE_RSS_URL: ${{ inputs.override_rss_url }}
run: |
set -euo pipefail

APP_JSON=$(yq -o=json '.apps' deployed-apps.yml | jq -c --arg key "$APP_KEY" '.[$key] // empty')
if [ -z "$APP_JSON" ]; then
echo "::error::No app '$APP_KEY' in deployed-apps.yml."
exit 1
fi

field() {
jq -r --arg f "$1" '.[$f] // "" | tostring' <<<"$APP_JSON"
}

APP_NAME=$(field app_name)
DESCRIPTION="${OVERRIDE_DESCRIPTION:-$(field description)}"
ICON_URL="${OVERRIDE_ICON_URL:-$(field icon_url)}"
RSS_TITLE="${OVERRIDE_RSS_TITLE:-$(field rss_title)}"
RSS_URL="${OVERRIDE_RSS_URL:-$(field rss_url)}"
EDGE_APP_ID=$(jq -r --arg env "$ENVIRONMENT" '(.ids // {})[$env] // "" | tostring' <<<"$APP_JSON")

for name in APP_NAME DESCRIPTION ICON_URL RSS_TITLE RSS_URL; do
if [ -z "${!name}" ]; then
echo "::error::'$APP_KEY' in deployed-apps.yml is missing $(tr '[:upper:]' '[:lower:]' <<<"$name")."
exit 1
fi
done

# The shared actions take the id as an input, so the manifest must
# not carry one
export DESCRIPTION ICON_URL RSS_TITLE RSS_URL
yq -i '
del(.id) |
.description = strenv(DESCRIPTION) |
.icon = strenv(ICON_URL) |
.settings.rss_title.default_value = strenv(RSS_TITLE) |
.settings.rss_url.default_value = strenv(RSS_URL)
' screenly.yml

{
echo "app_name=$APP_NAME"
echo "edge_app_id=$EDGE_APP_ID"
} >> "$GITHUB_OUTPUT"

- name: Show manifest for ${{ inputs.app_key }}
shell: bash
run: cat screenly.yml
3 changes: 2 additions & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ updates:
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'monthly'
interval: 'weekly'
target-branch: 'development'
groups:
github-actions:
patterns:
Expand Down
13 changes: 9 additions & 4 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
---
name: Checks

on:
push:
branches:
- development
- main
- master
pull_request:
branches:
- development
- main
- master

permissions:
contents: read

jobs:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: Screenly/edge-apps-actions/checks@v1
uses: Screenly/edge-apps-actions/.github/workflows/checks.yml@v26.10.2
39 changes: 27 additions & 12 deletions .github/workflows/initialize-edge-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,35 @@ on:
required: true
type: string

permissions:
contents: read

run-name: Initializing ${{ inputs.edge_app_name }} in ${{ inputs.environment }}

jobs:
initialize:
name: Initializing ${{ inputs.edge_app_name }} in ${{ inputs.environment }}
# The reusable workflow builds whatever ref this run was started from, so
# refuse anything but the default branch rather than initializing an app
# (possibly in production) from unreleased code. This fails loudly instead
# of skipping, so a run from the wrong branch can't look like a success.
verify-ref:
name: Verify default branch
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v7
with:
ref: main
- uses: Screenly/edge-apps-actions/initialize@v1
with:
screenly_api_token: ${{ secrets.SCREENLY_API_TOKEN }}
edge_app_name: ${{ inputs.edge_app_name }}
edge_app_title: ${{ inputs.edge_app_title }}
environment: ${{ inputs.environment }}
- name: Require the default branch
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
if [ "$GITHUB_REF" != "refs/heads/$DEFAULT_BRANCH" ]; then
echo "::error::Initialize Edge App must be run from $DEFAULT_BRANCH, not $GITHUB_REF_NAME."
exit 1
fi

initialize:
needs: verify-ref
uses: Screenly/edge-apps-actions/.github/workflows/initialize.yml@v26.10.2
with:
environment: ${{ inputs.environment }}
edge_app_name: ${{ inputs.edge_app_name }}
edge_app_title: ${{ inputs.edge_app_title }}
secrets:
SCREENLY_API_TOKEN: ${{ secrets.SCREENLY_API_TOKEN }}
150 changes: 64 additions & 86 deletions .github/workflows/initialize-rss-reader-app.yml
Original file line number Diff line number Diff line change
@@ -1,116 +1,94 @@
---
# Creates a feed app (e.g. BBC News) in one environment. Add the app to
# deployed-apps.yml first; this reads its name, description, icon and feed
# from there, then runs the shared edge-apps-actions initialize. Afterwards,
# put the new id in deployed-apps.yml so Update RSS Reader Apps deploys it.
name: Initialize Custom RSS Reader App

on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to initialize in (stage or production)'
description: 'Environment to initialize in'
required: true
default: 'stage'
type: choice
options:
- stage
- production

app_name:
description: 'App Name (used for instance title)'
app_key:
description: "App key in deployed-apps.yml (e.g. 'bbc-news')"
required: true
type: string
default: 'BBC News'

app_description:
description: 'App Description (used in manifest description)'
required: true
type: string
default: 'Latest news from BBC World Service'

rss_title:
description: 'RSS Title (title to display in the app)'
required: true
type: string
default: 'BBC News'

icon_url:
description: 'Icon URL (publicly accessible icon image)'
required: true
type: string
default: 'https://playground.srly.io/edge-apps/rss-reader/static/img/icon.svg'

rss_url:
description: 'RSS Feed URL'
required: true
type: string
default: 'http://feeds.bbci.co.uk/news/rss.xml'
permissions:
contents: read

run-name: Initialize RSS Reader - ${{ inputs.app_name }} in ${{ inputs.environment }}
run-name: Initialize RSS Reader - ${{ inputs.app_key }} in ${{ inputs.environment }}

jobs:
deploy:
name: Initializing ${{ inputs.app_name }} in ${{ inputs.environment }}
initialize:
name: Initialize ${{ inputs.app_key }} in ${{ inputs.environment }}
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
env:
API_BASE_URL: ${{ inputs.environment == 'stage' && 'https://api.screenlyappstage.com' || 'https://api.screenlyapp.com' }}
APP_NAME: ${{ inputs.app_name }}
SCREENLY_API_TOKEN: ${{ secrets.SCREENLY_API_TOKEN }}
MANIFEST_FILE_NAME: ${{ inputs.environment == 'stage' && 'screenly_qc.yml' || 'screenly.yml' }}
concurrency:
group: feed-app-${{ inputs.environment }}-${{ inputs.app_key }}
cancel-in-progress: false

steps:
- name: Checkout Repository
uses: actions/checkout@v7
with:
ref: main

- name: Setup yq
uses: ./.github/actions/setup-yq

- name: Update manifest file with custom values
# The app is built from the ref this run starts on, so refuse anything
# but the default branch rather than creating it from unreleased code
- name: Require the default branch
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
yq -i 'del(.id)' "$MANIFEST_FILE_NAME"
yq -i '.description = "${{ inputs.app_description }}"' "$MANIFEST_FILE_NAME"
yq -i '.icon = "${{ inputs.icon_url }}"' "$MANIFEST_FILE_NAME"
yq -i '.settings.rss_url.default_value = "${{ inputs.rss_url }}"' "$MANIFEST_FILE_NAME"
yq -i '.settings.rss_title.default_value = "${{ inputs.rss_title }}"' "$MANIFEST_FILE_NAME"

- name: Show updated manifest
run: cat "$MANIFEST_FILE_NAME"

- name: Set up Bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Create Edge App
uses: screenly/cli@master
with:
screenly_api_token: ${{ env.SCREENLY_API_TOKEN }}
cli_commands: edge-app create --name="${{ env.APP_NAME }}" --in-place

- name: Build
run: bun run build

- name: Deploy Edge App
uses: screenly/cli@master
with:
screenly_api_token: ${{ env.SCREENLY_API_TOKEN }}
cli_commands: edge-app deploy --path="./dist"
if [ "$GITHUB_REF" != "refs/heads/$DEFAULT_BRANCH" ]; then
echo "::error::Run this from $DEFAULT_BRANCH, not $GITHUB_REF_NAME."
exit 1
fi

- name: Log manifest after creation
run: cat "dist/$MANIFEST_FILE_NAME"
- uses: actions/checkout@v7

- name: Create Instance
uses: screenly/cli@master
- name: Apply ${{ inputs.app_key }} config
id: config
uses: ./.github/actions/apply-feed-app
with:
screenly_api_token: ${{ env.SCREENLY_API_TOKEN }}
cli_commands: edge-app instance create --name="${{ inputs.app_name }}"
app_key: ${{ inputs.app_key }}
environment: ${{ inputs.environment }}

- name: Update Instance
uses: screenly/cli@master
# Refuses to run if deployed-apps.yml already has an id for this
# environment, or if an app with this name already exists
- name: Initialize ${{ inputs.app_key }}
uses: Screenly/edge-apps-actions/initialize@v26.10.2
with:
screenly_api_token: ${{ env.SCREENLY_API_TOKEN }}
cli_commands: edge-app instance update

- name: Log instance.yml
run: cat instance.yml
screenly_api_token: ${{ secrets.SCREENLY_API_TOKEN }}
environment: ${{ inputs.environment }}
edge_app_name: ${{ steps.config.outputs.app_name }}
Comment thread
salmanfarisvp marked this conversation as resolved.
Resolved
edge_app_title: ${{ steps.config.outputs.app_name }}
edge_app_id: ${{ steps.config.outputs.edge_app_id }}

# The shared action's summary says to set a repo variable; feed apps
# keep their ids in deployed-apps.yml instead. Runs even if a later
# step failed, as long as the app was created.
- name: Report where the id goes
if: always()
env:
APP_KEY: ${{ inputs.app_key }}
ENVIRONMENT: ${{ inputs.environment }}
run: |
ID="$(grep -E '^id:[[:space:]]*' screenly.yml | head -1 | awk '{print $2}' | tr -d "\"'" || true)"
[ -n "$ID" ] || exit 0
echo "::notice::Feed app id: set apps.$APP_KEY.ids.$ENVIRONMENT to $ID in deployed-apps.yml (not a repo variable)."
{
echo "## Feed app id"
echo ""
echo "This is a feed app, so ignore the note above about repository variables. Set this in \`deployed-apps.yml\` and merge it:"
echo ""
echo '```yaml'
echo "apps:"
echo " $APP_KEY:"
echo " ids:"
echo " $ENVIRONMENT: '$ID'"
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
Loading
Loading