Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 0 additions & 7 deletions .github/ISSUE_TEMPLATE/config.yml

This file was deleted.

40 changes: 0 additions & 40 deletions .github/ISSUE_TEMPLATE/dev-task.yml

This file was deleted.

16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/error.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Error
description: Algo no funciona como debería.
type: Bug
body:
- type: textarea
id: que-ocurrio
attributes:
label: ¿Qué ocurrió?
description: Qué hizo, qué esperaba y qué pasó.
validations:
required: true
- type: textarea
id: pasos
attributes:
label: Pasos para reproducirlo
description: Los comandos exactos y dónde se ejecutan (servidor, contenedor o navegador).
28 changes: 0 additions & 28 deletions .github/ISSUE_TEMPLATE/owner-task.yml

This file was deleted.

14 changes: 14 additions & 0 deletions .github/ISSUE_TEMPLATE/tarea.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Tarea
description: Un trabajo por hacer.
type: Task
body:
- type: textarea
id: que-hacer
attributes:
label: ¿Qué hay que hacer?
validations:
required: true
- type: textarea
id: listo
attributes:
label: ¿Cómo sabremos que está listo?
25 changes: 4 additions & 21 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,4 @@
<!-- Keep it short. The gate lives in CONTRIBUTING.md; this template just checks it. -->

## What & why

<!-- One or two sentences: what changes, and why. Link the issue/story if there is one. -->

Closes #

## Checklist

- [ ] Title follows **Conventional Commits** (`feat:`, `fix:`, `docs:`, `chore:`, `test:`…).
- [ ] The repository's own gate passes locally — the same one CI runs.
- [ ] Docs updated where a fact changed (one owner per fact — no duplication).
- [ ] Small and reviewable; **1 approval** before merge.

## AI involvement

<!-- Required if any AI assistance was used. Add the `ai-assisted` label and describe it below. -->

- [ ] This PR was written **with AI assistance** → labeled `ai-assisted`.
- [ ] Human-reviewed. <!-- If not yet reviewed by a human, say so here explicitly. -->
- [ ] El título está en inglés y sigue Conventional Commits.
- [ ] La compuerta del repositorio está en verde, o el PR indica qué no se ejecutó.
- [ ] El sitio de documentación está al día si cambió un hecho.
- [ ] Lleva la etiqueta `ai-assisted` si una IA ayudó.
5 changes: 5 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# actionlint 1.7.12 predates the documented job.workflow_* context, which app-release.yml reads.
paths:
.github/workflows/app-release.yml:
ignore:
- 'property "workflow_(repository|sha|ref)" is not defined'
162 changes: 162 additions & 0 deletions .github/workflows/app-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# SPDX-FileCopyrightText: 2026 APS Conecta
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# The shared app release. An app repo calls it, pinned by commit SHA, on pull requests and on v* tags:
#
# on:
# pull_request:
# push:
# tags: ["v*"]
# jobs:
# release:
# uses: APS-Conecta/.github/.github/workflows/app-release.yml@<commit sha> # <date>
# permissions:
# contents: write
# with:
# app-id: <info.xml id>
# secrets:
# APP_SIGNING_KEY: ${{ secrets.APP_SIGNING_KEY }}
# APP_SIGNING_KEY_PASSWORD: ${{ secrets.APP_SIGNING_KEY_PASSWORD }}
#
# A pull request builds and packs. A v* tag also checks the tag against info.xml and the vendored
# aps-common copies, then, inside the caller's protected `release` environment (the app key's only
# home), signs SHA256SUMS, proves it against the suite's apps.pub and publishes
# <id>.tar.gz, info.xml, SHA256SUMS and SHA256SUMS.minisig. The build job never sees the key.
name: App release

on:
workflow_call:
inputs:
app-id:
description: The app id, as in appinfo/info.xml.
required: true
type: string
app-dir:
description: The app's directory in the repo.
default: "."
type: string
node-version:
description: The Node.js version the build runs on.
default: "24"
type: string
build:
description: The build command, run in app-dir.
default: npm ci && npm run build
type: string
publish:
description: Publish on a v* tag. False only builds and packs.
default: true
type: boolean
secrets:
APP_SIGNING_KEY:
description: The app key (the .sec file's contents), from the caller's release environment.
required: false
APP_SIGNING_KEY_PASSWORD:
description: The app key's passphrase.
required: false

permissions: {}

jobs:
build:
name: Build and pack
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: read
env:
APP_ID: ${{ inputs.app-id }}
APP_DIR: app/${{ inputs.app-dir }}
TAG: ${{ github.ref_name }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
path: app
persist-credentials: false
- name: Check out the packer at this workflow's own commit
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: ${{ job.workflow_repository }}
ref: ${{ job.workflow_sha }}
path: tools
persist-credentials: false
- name: The tag is v + info.xml's version
if: github.ref_type == 'tag'
run: bash tools/scripts/pack-app.sh tag "$APP_DIR" "$TAG"
- name: The vendored aps-common copies equal aps-common
if: github.ref_type == 'tag'
run: bash tools/scripts/pack-app.sh parity "$APP_DIR"
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
with:
node-version: ${{ inputs.node-version }}
package-manager-cache: false
- name: Build
working-directory: app/${{ inputs.app-dir }}
env:
BUILD: ${{ inputs.build }}
run: bash -euo pipefail -c "$BUILD"
- name: Pack
run: bash tools/scripts/pack-app.sh pack "$APP_ID" "$APP_DIR" dist
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: app-release
path: dist/
if-no-files-found: error

publish:
name: Sign and publish
needs: build
if: inputs.publish && github.ref_type == 'tag' && startsWith(github.ref_name, 'v')
runs-on: ubuntu-24.04
timeout-minutes: 15
environment: release
permissions:
contents: write
env:
APP_ID: ${{ inputs.app-id }}
TAG: ${{ github.ref_name }}
steps:
- name: The caller pins this workflow by commit SHA
env:
WORKFLOW_REF: ${{ job.workflow_ref }}
run: |
[[ "$WORKFLOW_REF" =~ @[0-9a-f]{40}$ ]] \
|| { echo "::error::call app-release.yml by commit SHA, not @${WORKFLOW_REF##*@}"; exit 1; }
- name: Check out the packer at this workflow's own commit
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: ${{ job.workflow_repository }}
ref: ${{ job.workflow_sha }}
path: tools
persist-credentials: false
- name: Check out apps.pub, the app key the installer trusts
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: APS-Conecta/instalador
ref: main
path: suite
sparse-checkout: apps.pub
sparse-checkout-cone-mode: false
persist-credentials: false
- name: Install signify
run: |
sudo apt-get update -qq && sudo apt-get install -y signify-openbsd
command -v signify >/dev/null || sudo ln -sf "$(command -v signify-openbsd)" /usr/local/bin/signify
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
name: app-release
path: dist
- name: Sign and prove against apps.pub
env:
APP_SIGNING_KEY: ${{ secrets.APP_SIGNING_KEY }}
APP_SIGNING_KEY_PASSWORD: ${{ secrets.APP_SIGNING_KEY_PASSWORD }}
run: bash tools/scripts/pack-app.sh sign dist suite/apps.pub
- name: Publish the release, latest only for the highest version
env:
GH_TOKEN: ${{ github.token }}
run: |
top="$(gh api --paginate "repos/$GITHUB_REPOSITORY/tags" --jq '.[].name' \
| grep -E '^v[0-9]+(\.[0-9]+)+$' | sort -V | tail -n 1)"
latest=false; [ "$top" = "$TAG" ] && latest=true
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --verify-tag --generate-notes --latest="$latest" \
"dist/$APP_ID.tar.gz" dist/info.xml dist/SHA256SUMS dist/SHA256SUMS.minisig
56 changes: 56 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# SPDX-FileCopyrightText: 2026 APS Conecta
# SPDX-License-Identifier: AGPL-3.0-or-later
name: CI

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
self-test:
name: Packer self-test
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install signify
run: |
sudo apt-get update -qq && sudo apt-get install -y signify-openbsd
command -v signify >/dev/null || sudo ln -sf "$(command -v signify-openbsd)" /usr/local/bin/signify
- run: shellcheck scripts/pack-app.sh
- run: bash scripts/pack-app.sh --self-test

lint:
name: actionlint and zizmor
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: actionlint 1.7.12
run: |
curl -fsSLo "$RUNNER_TEMP/actionlint.tar.gz" \
https://github.com/rhysd/actionlint/releases/download/v1.7.12/actionlint_1.7.12_linux_amd64.tar.gz
echo "8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 $RUNNER_TEMP/actionlint.tar.gz" | sha256sum -c -
tar -xzf "$RUNNER_TEMP/actionlint.tar.gz" -C "$RUNNER_TEMP" actionlint
"$RUNNER_TEMP/actionlint"
- name: zizmor 1.31.1
run: pipx run zizmor==1.31.1 .github/workflows

fixture:
name: Fixture caller
# zizmor prefers $/ over ./ here; actionlint 1.7.12 cannot parse $/ yet.
uses: ./.github/workflows/app-release.yml # zizmor: ignore[self-repository]
permissions:
contents: write # GitHub checks the nested publish job's grant before its if:; publish: false skips it
with:
app-id: fixture
app-dir: tests/fixture
publish: false
Loading