Skip to content
Draft
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
246 changes: 246 additions & 0 deletions .github/actions/upload/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
name: "Upload Debian to Artifactory"
description: "Uploads Debian artifacts from a .changes file to Artifactory"

inputs:
server_url:
description: "Artifactory server URL"
required: false
default: "https://qartifactory.pe.jfrog.io"

target_base_repo:
description: "Target repo name (e.g. deb-local or deb-remote)"
required: false
default: "qsc-debian-local"

changes_path:
description: "Path to .changes file"
required: true

provenance_info:
description: "Extra artifactory properties"
required: false
default: "{}"

access_token:
description: "Artifactory access token (mutually exclusive with qsc_api_key)"
required: false

qsc_api_key:
description: "QSC API key - used to generate a temporary access token (mutually exclusive with access_token)"
required: false

access_token_data:
description: "Access token data for generating access token - used in conjunction with qsc_api_key"
required: false
default: "{\"softwareName\":\"LU.QCLINUX\",\"softwareType\":\"SoftwareImage\",\"releaseTag\":\"2.0\"}"

component:
description: "Component name"
required: false
default: "main"

debug:
description: "Enable debug output directory in target repo (appends {{github.run_id}} to target path)"
required: false
default: false

runs:
using: "composite"
steps:

# This step checks for the presence of required Debian packaging tools and installs them if they are missing.
# The user is encouraged to install these dependencies in their environment beforehand to speed up the workflow,
# but this step ensures that the action can run successfully even if they are not pre-installed.
- name: Install dependencies if needed
shell: bash
run: |
set -euo pipefail

# Sudo if needed
SUDO=sudo
if [ "$(id -u)" = 0 ]; then SUDO=""; fi

# List the debian package names you require
required=(devscripts dctrl-tools jq curl)

# Collect missing packages
missing=()
for pkg in "${required[@]}"; do
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
missing+=("$pkg")
fi
done

# Install only if something is missing
if ((${#missing[@]})); then
echo "Installing missing packages: ${missing[*]}"
# Noninteractive + lean + quiet
export DEBIAN_FRONTEND=noninteractive
$SUDO apt-get update -y -qq
$SUDO apt-get install -y -qq --no-install-recommends "${missing[@]}"
else
echo "All prerequisites already installed."
fi

- name: Setup JFrog CLI
uses: jfrog/setup-jfrog-cli@v4
with:
version: latest

- name: Generate access token if qsc_api_key is provided, otherwise use provided access_token
id: gen_token
shell: bash
env:
ACCESS_TOKEN_URL: "https://apigwx-aws.qualcomm.com/saga/api/qsc/v1/chipSoftware/component/artifactory/release/artifact/debian/public/create/token"
run: |
set -euo pipefail

if [ -z "${{ inputs.qsc_api_key }}" ] && [ -z "${{ inputs.access_token }}" ]; then
echo "ERROR: Neither qsc_api_key nor access_token provided."
exit 1
fi

if [ -n "${{ inputs.qsc_api_key }}" ] && [ -n "${{ inputs.access_token }}" ]; then
echo "ERROR: Both qsc_api_key and access_token were provided. These are not compatible."
exit 1
fi

if [ -n "${{ inputs.access_token }}" ]; then
echo "Using provided access_token..."
echo "access_token=${{ inputs.access_token }}" >> $GITHUB_OUTPUT
exit 0
fi

echo "Generating access token using qsc_api_key..."

response=$(curl -s \
-X POST "${{env.ACCESS_TOKEN_URL}}" \
-H 'Content-Type: application/json' \
-H 'X-QCOM-TokenType: apikey' \
-H 'Authorization: ${{ inputs.qsc_api_key }}' \
-d '${{inputs.access_token_data}}')

token=$(echo "$response" | jq -r '.token')

if [ -z "$token" ] || [ "$token" = "null" ]; then
echo "ERROR: Failed to generate access token from qsc_api_key."
echo "Response was: $response"
exit 1
fi

echo "access_token=$token" >> $GITHUB_OUTPUT
echo "Access token generated successfully."

- name: Determine changes-file directory
id: changes_dir
shell: bash
run: |
set -euo pipefail

# compute directory portion of the provided changes_path (works if changes_path is a file or a directory)
CHANGES_FILE="${{ inputs.changes_path }}"
if [ -d "$CHANGES_FILE" ]; then
# input already a directory
dir="$CHANGES_FILE"
else
dir=$(dirname "$CHANGES_FILE")
fi

echo "changes_file_dir=$dir" >> $GITHUB_OUTPUT

- name: Parse .changes and provenance
working-directory: ${{ steps.changes_dir.outputs.changes_file_dir }}
shell: bash
env:
CHANGES_FILE_DIR: ${{ steps.changes_dir.outputs.changes_file_dir }}
PROVENANCE_INFO: ${{ inputs.provenance_info }}
run: |
set -euo pipefail

shopt -s nullglob

changes_files=( *.changes )

if (( ${#changes_files[@]} == 0 )); then
echo "ERROR: No .changes file found in $CHANGES_FILE_DIR" >&2
exit 1
fi

if (( ${#changes_files[@]} > 1 )); then
echo "ERROR: Multiple .changes files found in $CHANGES_FILE_DIR: ${changes_files[*]}" >&2
exit 1
fi

CHANGES_FILE="${changes_files[0]}"
echo "Using .changes file: $CHANGES_FILE"

SUITE="$(grep-dctrl -ns Distribution . "$CHANGES_FILE")"
SOURCE_PKG="$(grep-dctrl -ns Source . "$CHANGES_FILE")"
ALL_FILES=$(grep-dctrl -nsFiles . "$CHANGES_FILE" | awk '{print $5}' | tr '\n' ' ')

PROPS="deb.distribution=${SUITE};deb.component=${{ inputs.component }}"

for key in $(echo "$PROVENANCE_INFO" | jq -r 'keys[]'); do
val=$(echo "$PROVENANCE_INFO" | jq -r --arg k "$key" '.[$k]')
PROPS="${PROPS};${key}=${val}"
done

echo "ALL_FILES=$ALL_FILES" >> $GITHUB_ENV
echo "SOURCE_PKG=$SOURCE_PKG" >> $GITHUB_ENV
echo "SUITE=$SUITE" >> $GITHUB_ENV
echo "PROPS=$PROPS" >> $GITHUB_ENV

echo "Parsed .changes file:"
echo " Distribution: $SUITE"
echo " Source Package: $SOURCE_PKG"
echo " All Files: $ALL_FILES"
echo " JFrog Properties: $PROPS"

- name: Configure JFrog server
shell: bash
env:
SERVER_ID: "artifactory-server"
run: |
jf c add "$SERVER_ID" \
--url "${{ inputs.server_url }}" \
--access-token "${{ steps.gen_token.outputs.access_token }}" \
--interactive=false \

echo "JFrog CLI configured with server ID '$SERVER_ID' and URL '${{ inputs.server_url }}'"
jf c show

- name: Upload all artifacts with architecture detection
working-directory: ${{ inputs.changes_file_dir }}
shell: bash
env:
SERVER_ID: "artifactory-server"
run: |
TARGET_DIR="${{ inputs.target_base_repo }}/pool/$SOURCE_PKG/$SUITE/"

if [ "${{ inputs.debug }}" = "true" ]; then
echo "Debug mode enabled - appending run_id to target directory"
echo "Original TARGET_DIR: $TARGET_DIR"
TARGET_DIR="$TARGET_DIR/${{github.run_id}}/"
echo "Modified TARGET_DIR: $TARGET_DIR"
fi

for f in $ALL_FILES; do

if [[ "$f" =~ _arm64\.deb$ || "$f" =~ _arm64\.ddeb$ ]]; then
PROPS="${PROPS};deb.architecture=arm64"
elif [[ "$f" =~ _amd64\.deb$ || "$f" =~ _amd64\.ddeb$ ]]; then
PROPS="${PROPS};deb.architecture=amd64"
fi

echo "Uploading $f"
echo server_id: "$SERVER_ID"
echo "props: $PROPS"
echo "target: $TARGET_DIR"

jf rt upload \
--server-id="$SERVER_ID" \
--target-props "${PROPS}" \
"$f" \
"$TARGET_DIR"

done
55 changes: 39 additions & 16 deletions .github/workflows/qcom-release-reusable-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ on:
secrets:
TOKEN:
required: true
QSC_TOKEN:
required: true

permissions:
contents: read
Expand Down Expand Up @@ -69,7 +71,6 @@ jobs:
with:
repository: qualcomm-linux/qcom-build-utils
ref: ${{inputs.qcom-build-utils-ref}}
token: ${{secrets.TOKEN}}
path: ./qcom-build-utils
fetch-depth: 1
sparse-checkout: |
Expand Down Expand Up @@ -188,7 +189,8 @@ jobs:
"packages": $MAIN_PKGS_JSON,
"dev-packages": $DEV_PKGS_JSON,

"build_timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
"build_timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"workflow_url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
}
EOF
Expand All @@ -203,22 +205,11 @@ jobs:
pkg-dir: package-repo
build-dir: build

- name: Remove files with unauthorized characters
run: |
rm build/*.build

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: build/

# After the above step that changed the changlog from UNRELEASED to unstable, now create a new changelog entry
# that bumps the version for the next development cycle and sets the suite back to UNRELEASED
- name: Commit changelog suite change
working-directory: ./package-repo
run: |
cd ./package-repo

version=$(dpkg-parsechangelog --show-field Version)

# bump Debian revision (last hyphen-separated field), e.g. 1.0.0-1 -> 1.0.0-2
Expand All @@ -242,11 +233,32 @@ jobs:

git commit -a -m "Initial commit of new version ${newversion}"

git push origin ${{inputs.debian-branch}}
git push origin debian/${version}
#TODO reactivate those
#git push origin ${{inputs.debian-branch}}
#git push origin debian/${version}

git log --graph --oneline -n 10 --color=always

- name: Prepare build logs for upload
working-directory: ./build/
run: |
# Remove symlink and rename timestamped .build file to its base name
BUILD_LINK=$(find . -maxdepth 1 -name "*.build" -type l)
if [ -n "$BUILD_LINK" ]; then
BUILD_TARGET=$(readlink "$BUILD_LINK")
rm "$BUILD_LINK"
mv "$BUILD_TARGET" "$BUILD_LINK"
fi

# JFrog CLI does not allow colon characters in the properties, so we need to replace them with underscores in the build logs that are used to generate the properties for the upload step
sed -i 's/:/_/g' *.build

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: build/

upload-to-s3:
needs: pkg-release
runs-on: 'lecore-prd-u2404-arm64-xlrg-od-ephem'
Expand Down Expand Up @@ -285,3 +297,14 @@ jobs:
s3_bucket: qli-prd-lecore-gh-artifacts
path: build
destination: ${{ env.S3_BUCKET_PATH }}

- name: Notify qcom-distro-images of new release via repository dispatch
uses: peter-evans/repository-dispatch@v3
with:
token: ${{secrets.TOKEN}}
repository: qualcomm-linux/qcom-distro-images
event-type: pkg-repo-release
client-payload: >-
{
"artifact_path":"${{ env.S3_BUCKET_PATH }}"
}
Loading