Files
computer-playbook/roles/web-app-decidim/tasks/01_setup.yml
kevinveenbirkenbachandClaude Opus 5 ad7913d41a fix(decidim): create the organization that db:seed skips in production
Every task after the seed step reads `Decidim::Organization.first`
(ensure/default_pages.rb, set_organization_host.rb, ensure/admin_user.rb,
configure_oidc.rb), and only `rails db:seed` ever creates one. Decidim guards
its core seeds with `if !Rails.env.production? || ENV.fetch("SEED", nil)`
(decidim-core db/seeds.rb, v0.31.6) and this role sets no SEED, so in
production the seed step creates nothing, and `failed_when: false` hides it.
The next task then calls `CreateDefaultPages.call(nil)`, whose
`StaticPage.find_or_create_by!(organization:, slug:)` raises, and
set_organization_host.rb would follow with `nil.host =`.

The regular matrix deploys RAILS_ENV=development, where the seeds run, so
only the README replay step, which provisions a production inventory, gets
here. It has not got this far yet: the healthcheck stopped it first
(87ce146d8).

ensure/organization.rb creates the organization when there is none, with the
attributes Decidim's two creation paths agree on (the core seeds and
Decidim::System::CreateOrganization), plus the help pages and content blocks
CreateOrganization adds. It leaves out the admin invitation, because
ensure/admin_user.rb creates the administrator itself, and tos_version,
which the terms-of-service page sets when the next task creates it. Name and
reference prefix come from DECIDIM_ORGANIZATION_NAME, the host from the same
domain the other tasks use.

The task runs only where the seeds skip, with ENVIRONMENT == 'production'. In
development nothing changes, and a seed that fails there still surfaces at the
next task instead of being covered by a bare organization.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 10:53:55 +02:00

101 lines
4.6 KiB
YAML

---
- name: "🔍 Decidim | Resolve hosting node + container ID ({{ DEPLOYMENT_MODE }})"
ansible.builtin.include_tasks: "{{ lookup('path_absolute', 'roles/sys-svc-compose/tasks/utils/swarm/resolve_host_cid.yml') }}"
vars:
resolve_service_key: decidim
resolve_output_prefix: DECIDIM
resolve_compose_cid: "{{ DECIDIM_CONTAINER }}"
- name: "⏳ Decidim | Wait for web container to be healthy"
ansible.builtin.shell: >
container inspect --type container --format '{{ "{{.State.Health.Status}}" }}'
{{ DECIDIM_LOCAL_CID | quote }}
register: decidim_health
changed_when: false
retries: 60
delay: 15
until: (decidim_health.stdout | trim) == 'healthy'
delegate_to: "{{ DECIDIM_HOST_NODE }}"
- name: "▶️ Decidim | Run database migrations"
ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime
container exec -e RAILS_ENV={{ ENVIRONMENT | quote }}
{{ DECIDIM_LOCAL_CID | quote }}
bundle exec rails db:migrate
register: decidim_migrate_result
changed_when: decidim_migrate_result.stdout_lines | default([]) | length > 0
delegate_to: "{{ DECIDIM_HOST_NODE }}"
- name: "🌱 Decidim | Seed database on first deploy"
ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime
container exec -e RAILS_ENV={{ ENVIRONMENT | quote }}
{{ DECIDIM_LOCAL_CID | quote }}
bundle exec rails db:seed
register: decidim_seed_result
changed_when: decidim_seed_result.stdout_lines | default([]) | length > 0
failed_when: false
delegate_to: "{{ DECIDIM_HOST_NODE }}"
- name: "🏛️ Decidim | Create the organization that db:seed skips in production"
ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime
container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }}
-e DECIDIM_ORG_HOST={{ domain | quote }}
-e DECIDIM_ORG_NAME={{ DECIDIM_ORGANIZATION_NAME | quote }}
{{ DECIDIM_LOCAL_CID | quote }}
bundle exec rails runner -
args:
stdin: "{{ lookup('file', 'ruby/ensure/organization.rb') }}"
register: decidim_organization_result
changed_when: "'Organization created' in decidim_organization_result.stdout"
when: ENVIRONMENT == 'production'
delegate_to: "{{ DECIDIM_HOST_NODE }}"
- name: "📄 Decidim | Ensure default static pages exist (terms-of-service)"
ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime
container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }}
{{ DECIDIM_LOCAL_CID | quote }}
bundle exec rails runner -
args:
stdin: "{{ lookup('file', 'ruby/ensure/default_pages.rb') }}"
register: decidim_pages_result
changed_when: "'Default pages ensured' in decidim_pages_result.stdout"
delegate_to: "{{ DECIDIM_HOST_NODE }}"
- name: "🔧 Decidim | Set organization host"
ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime
container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }}
-e DECIDIM_ORG_HOST={{ domain | quote }}
{{ DECIDIM_LOCAL_CID | quote }}
bundle exec rails runner -
args:
stdin: "{{ lookup('file', 'ruby/set_organization_host.rb') }}"
register: decidim_org_result
changed_when: "'Organization host set to' in decidim_org_result.stdout"
delegate_to: "{{ DECIDIM_HOST_NODE }}"
- name: "✅ Decidim | Ensure administrator user exists with correct credentials"
ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime
container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }}
-e DECIDIM_ADMIN_EMAIL={{ lookup('users', 'administrator').email | quote }}
-e DECIDIM_ADMIN_PASSWORD={{ lookup('users', 'administrator').password | quote }}
{{ DECIDIM_LOCAL_CID | quote }}
bundle exec rails runner -
args:
stdin: "{{ lookup('file', 'ruby/ensure/admin_user.rb') }}"
register: decidim_admin_result
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
changed_when: "'Admin user ready' in decidim_admin_result.stdout"
delegate_to: "{{ DECIDIM_HOST_NODE }}"
- name: "🔧 Decidim | Configure OIDC omniauth settings in organization"
ansible.builtin.shell: > # nocheck: container-exec-resolver DECIDIM_LOCAL_CID resolved at delegate_to runtime
container exec -i -e RAILS_ENV={{ ENVIRONMENT | quote }}
{{ DECIDIM_LOCAL_CID | quote }}
bundle exec rails runner -
args:
stdin: "{{ lookup('file', 'ruby/configure_oidc.rb') }}"
register: decidim_oidc_result
changed_when: "'OIDC settings configured' in decidim_oidc_result.stdout"
when: DECIDIM_OIDC_ENABLED | bool
delegate_to: "{{ DECIDIM_HOST_NODE }}"