diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..bdce8a8 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,108 @@ +# ******************************************************************************* +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# ******************************************************************************* +name: Validate & Publish DevContainer +description: This workflow is checking that for releases, updates do not break stuff and publishes the released container. +on: + push: + tags: + - v[0-9]+.[0-9]+.[0-9]+ +jobs: + build: + strategy: + matrix: + os: [arm64, amd64] + include: + - os: amd64 + name: DevContainer (amd64) + runner: ubuntu-24.04 + - os: arm64 + name: DevContainer (arm64) + runner: ubuntu-24.04-arm + name: ${{ matrix.name }} + runs-on: ${{ matrix.runner }} + permissions: + contents: read + packages: write + id-token: write + steps: + - uses: eclipse-score/more-disk-space@v1 + - name: Checkout (GitHub) + uses: actions/checkout@v6 + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # Use .devcontainer from THIS repo for building and testing + - name: Check, Build, Test, Publish + uses: devcontainers/ci@v0.3 + with: + # The .devcontainer is never published as pre-built container. + # We want to only use it for building and testing the actual container, which resides in src/s-core-devcontainer. + push: never + runCmd: | + set -eux pipefail + + # Check + pre-commit run --show-diff-on-failure --color=always --all-files || exit 1 + + # Create builder for multi-arch builds + ./scripts/create_builder.sh + + # Build + ./scripts/build.sh --${{ matrix.os }} "${{ github.ref_name }}" "latest" + + # Test + ./scripts/test.sh + + # Publish + # We do not use the push feature of devcontainers/ci here, since that would push the wrong container. + # Instead, we use the publish script which pushes the correct container (residing in src/s-core-devcontainer). + # manually login to ghcr.io for publishing + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + ./scripts/publish.sh --${{ matrix.os }} "${{ github.ref_name }}" "latest" + merge: + name: Merge Labels + needs: [build] + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + id-token: write + steps: + - uses: eclipse-score/more-disk-space@v1 + - name: Checkout (GitHub) + uses: actions/checkout@v6 + - name: Login to GitHub Container Registry + uses: docker/login-action@v4 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # Use .devcontainer from THIS repo for building and testing + - name: Merge + uses: devcontainers/ci@v0.3 + with: + # The .devcontainer is never published as pre-built container. + # We want to only use it for building and testing the actual container, which resides in src/s-core-devcontainer. + push: never + runCmd: | + set -eux pipefail + + # Merge + # We do not use the push feature of devcontainers/ci here, since that would push the wrong container. + # Instead, we use the publish script which pushes the correct container (residing in src/s-core-devcontainer). + # manually login to ghcr.io for publishing + echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + ./scripts/merge.sh "${{ github.ref_name }}" "latest" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bdce8a8..312f26a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,99 +10,34 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* -name: Validate & Publish DevContainer -description: This workflow is checking that for releases, updates do not break stuff and publishes the released container. +name: DevContainer Release +description: This workflow creates a semantic version release when main changed since the last release tag. on: - push: - tags: - - v[0-9]+.[0-9]+.[0-9]+ + schedule: + - cron: '0 0 * * 1' + workflow_dispatch: +permissions: + contents: read # for checkout jobs: - build: - strategy: - matrix: - os: [arm64, amd64] - include: - - os: amd64 - name: DevContainer (amd64) - runner: ubuntu-24.04 - - os: arm64 - name: DevContainer (arm64) - runner: ubuntu-24.04-arm - name: ${{ matrix.name }} - runs-on: ${{ matrix.runner }} + release: + if: github.ref == 'refs/heads/main' permissions: - contents: read - packages: write - id-token: write + contents: write # to be able to publish a GitHub release + issues: write # to be able to comment on released issues + pull-requests: write # to be able to comment on released pull requests + name: release + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/devcontainers/javascript-node:4-24 steps: - - uses: eclipse-score/more-disk-space@v1 - - name: Checkout (GitHub) - uses: actions/checkout@v6 - - name: Login to GitHub Container Registry - uses: docker/login-action@v4 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - # Use .devcontainer from THIS repo for building and testing - - name: Check, Build, Test, Publish - uses: devcontainers/ci@v0.3 - with: - # The .devcontainer is never published as pre-built container. - # We want to only use it for building and testing the actual container, which resides in src/s-core-devcontainer. - push: never - runCmd: | - set -eux pipefail - - # Check - pre-commit run --show-diff-on-failure --color=always --all-files || exit 1 - - # Create builder for multi-arch builds - ./scripts/create_builder.sh - - # Build - ./scripts/build.sh --${{ matrix.os }} "${{ github.ref_name }}" "latest" - - # Test - ./scripts/test.sh - - # Publish - # We do not use the push feature of devcontainers/ci here, since that would push the wrong container. - # Instead, we use the publish script which pushes the correct container (residing in src/s-core-devcontainer). - # manually login to ghcr.io for publishing - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - ./scripts/publish.sh --${{ matrix.os }} "${{ github.ref_name }}" "latest" - merge: - name: Merge Labels - needs: [build] - runs-on: ubuntu-24.04 - permissions: - contents: read - packages: write - id-token: write - steps: - - uses: eclipse-score/more-disk-space@v1 - - name: Checkout (GitHub) - uses: actions/checkout@v6 - - name: Login to GitHub Container Registry - uses: docker/login-action@v4 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - # Use .devcontainer from THIS repo for building and testing - - name: Merge - uses: devcontainers/ci@v0.3 - with: - # The .devcontainer is never published as pre-built container. - # We want to only use it for building and testing the actual container, which resides in src/s-core-devcontainer. - push: never - runCmd: | - set -eux pipefail - - # Merge - # We do not use the push feature of devcontainers/ci here, since that would push the wrong container. - # Instead, we use the publish script which pushes the correct container (residing in src/s-core-devcontainer). - # manually login to ghcr.io for publishing - echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - ./scripts/merge.sh "${{ github.ref_name }}" "latest" + fetch-depth: 0 + fetch-tags: true + # this should have been done by the checkout action, but it doesn't work in a container, see https://github.com/actions/checkout/issues/766 + - run: git config --global --add safe.directory $PWD + # pinned version updated automatically by Dependabot. + # details at https://semantic-release.gitbook.io/semantic-release/usage/installation#global-installation + - run: npx semantic-release@25.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.releaserc b/.releaserc new file mode 100644 index 0000000..0cab322 --- /dev/null +++ b/.releaserc @@ -0,0 +1,10 @@ +{ + "branches": [ + "main" + ], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + "@semantic-release/github" + ] +} diff --git a/REUSE.toml b/REUSE.toml index fb1753d..d6231a3 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -29,3 +29,8 @@ path = ["resources/reopen_in_container.png", ] SPDX-FileCopyrightText = "Copyright (c) 2026 Contributors to the Eclipse Foundation" SPDX-License-Identifier = "Apache-2.0" + +[[annotations]] +path = [".releaserc"] +SPDX-FileCopyrightText = "Copyright (c) 2026 Contributors to the Eclipse Foundation" +SPDX-License-Identifier = "Apache-2.0" diff --git a/docs/README.md b/docs/README.md index 20f8a09..bb91971 100644 --- a/docs/README.md +++ b/docs/README.md @@ -98,3 +98,14 @@ It strengthens the supply chain by pinning versions and hashes, sourcing feature Pre-built images have a higer availability than the set of all tools which are installed (one download from a location controlled by S-CORE vs. many downloads from "everywhere"). Pre-built images can be easily archived anywhere, e.g. for reproducibility of builds in real production use-cases. It also enforces a clear separation of concerns: general tooling is delivered through reusable features, S-CORE–specific logic lives in a dedicated feature, and image composition plus publishing are centralized. + +## Release Automation + +Releases are cut automatically once per week from `main`, but only if commits were added since the latest `v..` tag. +The scheduled workflow creates the git tag and GitHub release, and the existing tag-triggered release workflow then builds, tests and publishes the matching container image. + +The next semantic version is derived from commit messages since the previous release: + +* breaking changes (`!` in the conventional commit header or `BREAKING CHANGE:` in the body) increment the major version +* `feat` commits increment the minor version +* every other commit increments the patch version so maintenance-only weeks still publish a new immutable image