Skip to content

Release 8.2.0 rc.1 (#12550) #78

Release 8.2.0 rc.1 (#12550)

Release 8.2.0 rc.1 (#12550) #78

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*'
branches:
- 'feat/release-pipeline**'
workflow_dispatch:
inputs:
version_override:
description: 'Version override (leave empty to auto-detect from latest tag)'
type: string
default: ''
env:
PRODUCTION_RELEASE_TAGS: '5.0,7,8'
DOCKER_REPO_ROLLING: owncloud/ocis-rolling
DOCKER_REPO_PRODUCTION: owncloud/ocis
NODE_VERSION: '24'
PNPM_VERSION: '10.28.1'
jobs:
determine-release-type:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.info.outputs.version }}
is_production: ${{ steps.info.outputs.is_production }}
is_prerelease: ${{ steps.info.outputs.is_prerelease }}
docker_repos: ${{ steps.info.outputs.docker_repos }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
if: ${{ github.ref_type == 'branch' || (github.event_name == 'workflow_dispatch' && inputs.version_override == '') }}
with:
fetch-depth: 0
fetch-tags: true
- id: info
run: |
next_dev() {
# If latest tag is already a pre-release (e.g. v8.0.2-dev.1), reuse its base
# version (8.0.2-dev.1) so repeated branch runs don't bump the patch counter.
# If latest tag is a production release (e.g. v8.0.1), increment patch (8.0.2-dev.1).
local tag=$(git tag --sort=-version:refname | grep -m1 '^v' || echo "v0.0.0")
local ver="${tag#v}"
if [[ "$ver" == *"-"* ]]; then
echo "${ver%%-*}-dev.1"
else
IFS='.' read -r M m p <<< "$ver"
echo "${M}.${m}.$((p + 1))-dev.1"
fi
}
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
VERSION="${{ inputs.version_override }}"
[[ -z "$VERSION" ]] && VERSION=$(next_dev)
elif [[ "${{ github.ref_type }}" == "branch" ]]; then
VERSION=$(next_dev)
else
VERSION="${GITHUB_REF#refs/tags/v}"
fi
IS_PRODUCTION=false
for TAG in ${PRODUCTION_RELEASE_TAGS//,/ }; do
[[ "$VERSION" == "$TAG"* ]] && IS_PRODUCTION=true && break
done
[[ "$VERSION" == *"-"* ]] && IS_PRERELEASE=true || IS_PRERELEASE=false
if [[ "$IS_PRODUCTION" == "true" && "$IS_PRERELEASE" == "false" ]]; then
REPOS=[\"$DOCKER_REPO_ROLLING\",\"$DOCKER_REPO_PRODUCTION\"]
else
REPOS=[\"$DOCKER_REPO_ROLLING\"]
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "is_production=$IS_PRODUCTION" >> $GITHUB_OUTPUT
echo "is_prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
echo "docker_repos=$REPOS" >> $GITHUB_OUTPUT
generate-code:
runs-on: ubuntu-latest
needs: [determine-release-type]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ env.NODE_VERSION }}
- run: npm install --silent -g yarn npx --force
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v4
with:
version: ${{ env.PNPM_VERSION }}
- run: pnpm config set store-dir ./.pnpm-store && make ci-node-generate
env:
CHROMEDRIVER_SKIP_DOWNLOAD: 'true'
- run: make ci-go-generate
env:
BUF_TOKEN: ${{ secrets.BUF_API_TOKEN }}
- name: bump LatestTag
run: |
VERSION="${{ needs.determine-release-type.outputs.version }}"
sed -i "s/LatestTag = \".*\"/LatestTag = \"$VERSION\"/" ocis-pkg/version/version.go
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: generated-code
path: |
.
!.git
retention-days: 1
docker-build:
name: docker-build (${{ matrix.arch }}, ${{ matrix.repo }})
runs-on: ${{ matrix.arch == 'amd64' && 'ubuntu-24.04' || 'ubuntu-24.04-arm' }}
needs: [determine-release-type, generate-code, security-scan-trivy]
strategy:
matrix:
arch: [amd64, arm64]
repo: ${{ fromJSON(needs.determine-release-type.outputs.docker_repos) }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: generated-code
path: .
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- id: goversion
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
- run: |
ALPINE_VERSION=$(grep '^FROM.*alpine:' ocis/docker/Dockerfile.linux.${{ matrix.arch }} | grep -o 'alpine:[0-9.]*' | cut -d: -f2 | cut -d. -f1,2)
docker run --rm \
-v "${{ github.workspace }}:/workspace" \
-w /workspace \
"golang:${{ steps.goversion.outputs.go-version }}-alpine${ALPINE_VERSION}" \
sh -c "apk add --no-cache bash gcc musl-dev vips-dev make git && \
git config --global --add safe.directory /workspace && \
CGO_ENABLED=1 ENABLE_VIPS=true VERSION=${{ needs.determine-release-type.outputs.version }} \
make -C ocis release-linux-docker-${{ matrix.arch }}"
- id: tags
run: |
VERSION="${{ needs.determine-release-type.outputs.version }}"
REPO="${{ matrix.repo }}"
ARCH="${{ matrix.arch }}"
printf "tags<<EOF\n%s\nEOF\n" \
"${REPO}:${VERSION}-linux-${ARCH}" >> $GITHUB_OUTPUT
- id: build
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: ocis
file: ocis/docker/Dockerfile.linux.${{ matrix.arch }}
platforms: linux/${{ matrix.arch }}
load: true
push: false
provenance: false
build-args: |
REVISION=${{ github.sha }}
VERSION=${{ needs.determine-release-type.outputs.version }}
tags: ${{ steps.tags.outputs.tags }}
- id: trivy
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
continue-on-error: true
with:
image-ref: ${{ steps.tags.outputs.tags }}
format: table
exit-code: 1
severity: HIGH,CRITICAL
ignore-unfixed: true
skip-files: /usr/bin/gomplate,/usr/bin/wait-for
hide-progress: true
env:
TRIVY_IGNOREFILE: .trivyignore
- name: Block on vulnerabilities
if: steps.trivy.outcome == 'failure'
run: |
echo "::error title=Security scan blocked release::Image ${{ steps.tags.outputs.tags }} has HIGH or CRITICAL vulnerabilities (see Trivy report above). Fix all findings before releasing."
exit 1
- name: push
if: steps.trivy.outcome == 'success'
run: docker push ${{ steps.tags.outputs.tags }}
docker-scan:
name: docker-scan (${{ matrix.arch }}, ${{ matrix.repo }})
runs-on: ubuntu-latest
needs: [determine-release-type, docker-build]
strategy:
matrix:
arch: [amd64]
repo: ${{ fromJSON(needs.determine-release-type.outputs.docker_repos) }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
id: trivy
continue-on-error: true
with:
image-ref: ${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}-linux-${{ matrix.arch }}
format: table
exit-code: 1
severity: HIGH,CRITICAL
ignore-unfixed: true
skip-files: /usr/bin/gomplate,/usr/bin/wait-for
hide-progress: true
env:
TRIVY_IGNOREFILE: .trivyignore
- name: Block on vulnerabilities
if: steps.trivy.outcome == 'failure'
run: |
echo "::error title=Security scan blocked release::Image ${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}-linux-${{ matrix.arch }} has HIGH or CRITICAL vulnerabilities (see Trivy report above). Fix all findings before releasing."
exit 1
docker-manifest:
name: docker-manifest (${{ matrix.repo }})
runs-on: ubuntu-latest
needs: [determine-release-type, docker-build, docker-scan]
strategy:
matrix:
repo: ${{ fromJSON(needs.determine-release-type.outputs.docker_repos) }}
steps:
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- if: ${{ contains(matrix.repo, 'rolling') }}
run: |
docker buildx imagetools create \
-t "${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}" \
"${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}-linux-amd64" \
"${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}-linux-arm64"
- if: ${{ !contains(matrix.repo, 'rolling') }}
run: |
docker buildx imagetools create \
-t "${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}" \
"${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}-linux-amd64" \
"${{ matrix.repo }}:${{ needs.determine-release-type.outputs.version }}-linux-arm64"
docker-readme:
name: docker-readme (${{ matrix.repo }})
runs-on: ubuntu-latest
needs: [determine-release-type, docker-manifest]
strategy:
matrix:
repo: ${{ fromJSON(needs.determine-release-type.outputs.docker_repos) }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5.0.0
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
repository: ${{ matrix.repo }}
readme-filepath: ocis/README.md
build-binaries:
name: build-binaries (${{ matrix.os }})
runs-on: ubuntu-latest
needs: [determine-release-type, generate-code]
strategy:
matrix:
os: [linux, darwin]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: generated-code
path: .
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
- run: |
make -C ocis release-${{ matrix.os }} OUTPUT=${{ needs.determine-release-type.outputs.version }}
make -C ocis release-finish
if [[ "${{ matrix.os }}" == "linux" ]]; then
cp assets/End-User-License-Agreement-for-ownCloud-Infinite-Scale.pdf ocis/dist/release/
fi
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: binaries-${{ matrix.os }}
path: ocis/dist/release/*
retention-days: 1
security-scan-trivy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
format: table
exit-code: 1
severity: CRITICAL,HIGH
trivy-config: .trivy.yaml
license-check:
runs-on: ubuntu-latest
needs: [determine-release-type, generate-code]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: generated-code
path: .
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ env.NODE_VERSION }}
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
- run: npm install --silent -g yarn npx "pnpm@$PNPM_VERSION" --force
- run: make ci-node-check-licenses && make ci-node-save-licenses
- run: make ci-go-check-licenses && make ci-go-save-licenses
- run: tar -czf third-party-licenses.tar.gz -C third-party-licenses .
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: third-party-licenses
path: third-party-licenses.tar.gz
retention-days: 1
generate-changelog:
runs-on: ubuntu-latest
needs: [determine-release-type]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version-file: go.mod
- run: |
make changelog CHANGELOG_VERSION=$(echo "${{ needs.determine-release-type.outputs.version }}" | cut -d'-' -f1)
# calens produces empty output when no versioned changelog directory exists (e.g. dev builds).
# Fall back to a pointer to the unreleased entries.
if [[ $(wc -l < ocis/dist/CHANGELOG.md) -lt 5 ]]; then
echo "Development release — no release notes yet. See [unreleased changes](https://github.com/owncloud/ocis/tree/master/changelog/unreleased/)." > ocis/dist/CHANGELOG.md
fi
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: changelog
path: ocis/dist/CHANGELOG.md
retention-days: 1
create-github-release:
runs-on: ubuntu-latest
needs: [determine-release-type, build-binaries, license-check, generate-changelog, security-scan-trivy, docker-readme]
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: binaries-linux
path: release-assets
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: binaries-darwin
path: release-assets
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: third-party-licenses
path: release-assets
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: changelog
path: .
- uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
with:
tag_name: v${{ needs.determine-release-type.outputs.version }}
name: v${{ needs.determine-release-type.outputs.version }}
body_path: CHANGELOG.md
prerelease: ${{ needs.determine-release-type.outputs.is_prerelease == 'true' }}
files: release-assets/*
audit-release:
runs-on: ubuntu-latest
needs:
- determine-release-type
- generate-code
- docker-build
- docker-scan
- docker-manifest
- docker-readme
- build-binaries
- security-scan-trivy
- license-check
- generate-changelog
- create-github-release
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: binaries-linux
path: release-assets
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: binaries-darwin
path: release-assets
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: third-party-licenses
path: release-assets
- run: |
python3 scripts/audit-release.py \
--version "${{ needs.determine-release-type.outputs.version }}" \
--dir release-assets/ \
--github-release --docker
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}