|
| 1 | +name: 'Docker Deploy Action' |
| 2 | + |
| 3 | +description: > |
| 4 | + 🪂 A Github Action to deploy pages conveniently |
| 5 | +
|
| 6 | +branding: |
| 7 | + icon: 'command' |
| 8 | + color: 'red' |
| 9 | + |
| 10 | +inputs: |
| 11 | + id: |
| 12 | + description: The deploy id |
| 13 | + required: false |
| 14 | + hub_username: |
| 15 | + description: Username for Docker Hub |
| 16 | + default: ${{ github.actor }} |
| 17 | + required: true |
| 18 | + hub_password: |
| 19 | + description: Docker Hub authentication token |
| 20 | + required: true |
| 21 | + hub_token: |
| 22 | + description: Docker Hub authentication token |
| 23 | + required: true |
| 24 | + action_path: |
| 25 | + description: Path to the dockerfile from which to build the image |
| 26 | + required: true |
| 27 | + credentials: |
| 28 | + description: 'The gcloud credentials' |
| 29 | + required: true |
| 30 | + image_name: |
| 31 | + description: Tag to use for the new image |
| 32 | + default: ${{ github.action_repository }} |
| 33 | + required: true |
| 34 | + dockerfile_path: |
| 35 | + description: Path to the dockerfile from which to build the image |
| 36 | + required: true |
| 37 | + initiate_pauli_sum: |
| 38 | + description: Build args |
| 39 | + required: false |
| 40 | + default: "" |
| 41 | + docker_hub_repo_short_description: |
| 42 | + description: Short description text for the docker hub repo |
| 43 | + required: true |
| 44 | + docker_hub_repo_readme_file_path: |
| 45 | + description: | |
| 46 | + Path of the md file which will be used as the docker hub repo readme |
| 47 | + required: true |
| 48 | + cache_src: |
| 49 | + description: Path for the docker cache source |
| 50 | + required: false |
| 51 | + default: /tmp/.buildx-cache |
| 52 | + cache_dest: |
| 53 | + description: Path for the docker cache destination |
| 54 | + required: false |
| 55 | + default: /tmp/.buildx-cache-new |
| 56 | + owner: |
| 57 | + description: 'The deploy owner' |
| 58 | + required: false |
| 59 | + token: |
| 60 | + description: 'The deploy token' |
| 61 | + required: false |
| 62 | + repository: |
| 63 | + description: 'The deploy repository' |
| 64 | + default: ${{ github.repository }} |
| 65 | + required: false |
| 66 | + api_key: |
| 67 | + description: The key of api application |
| 68 | + required: true |
| 69 | + api_secret: |
| 70 | + description: The secret of api application |
| 71 | + required: true |
| 72 | + pypi_token: |
| 73 | + description: The pypi token |
| 74 | + required: true |
| 75 | + bot_token: |
| 76 | + description: The monitor token |
| 77 | + required: true |
| 78 | + logs_token: |
| 79 | + description: The warning token |
| 80 | + required: true |
| 81 | + chat_id: |
| 82 | + description: The telegram chat id |
| 83 | + required: true |
| 84 | + |
| 85 | +outputs: |
| 86 | + artifact: |
| 87 | + description: Collect artifact outputs |
| 88 | + value: ${{ toJSON(steps.artifact.outputs) }} |
| 89 | + variables: |
| 90 | + description: Collect variables outputs |
| 91 | + value: ${{ toJSON(steps.variables.outputs) }} |
| 92 | + |
| 93 | +runs: |
| 94 | + using: composite |
| 95 | + steps: |
| 96 | + - name: Remove Existing Connection |
| 97 | + shell: bash |
| 98 | + env: |
| 99 | + RUN: ${{ github.run_id }} |
| 100 | + USER: ${{ github.actor }} |
| 101 | + REPO: ${{ github.repository }} |
| 102 | + ACTOR: ${{ github.triggering_actor }} |
| 103 | + OWNER: ${{ github.repository_owner }} |
| 104 | + run: | |
| 105 | + gh variable set RERUN_RUNNER --body "false" |
| 106 | +
|
| 107 | + HEADER="Accept: application/vnd.github+json" |
| 108 | + RESPONSE=$(gh api -H "${HEADER}" repos/${{ github.repository }}/actions/runners) |
| 109 | + TOTAL_COUNT=$(gh api -H "${HEADER}" /repos/${{ github.repository }}/actions/runners --jq '.total_count') |
| 110 | + STATUS=$(echo "$RESPONSE" | jq -r --arg NAME "${{ env.RUNNER_TITLE }}" '.runners[] | select(.name == $NAME).status') |
| 111 | +
|
| 112 | + if [[ "$TOTAL_COUNT" -eq 0 ]]; then |
| 113 | + export "RUNNER_COUNT=$TOTAL_COUNT" |
| 114 | + gh variable set RERUN_RUNNER --body "true" |
| 115 | + elif [[ "$STATUS" == "offline" ]]; then |
| 116 | + export "RUNNER_STATUS=$STATUS" |
| 117 | + gh variable set RERUN_RUNNER --body "true" |
| 118 | + RUNNER_ID=$(gh api -H "${HEADER}" /repos/${{ github.repository }}/actions/runners --jq '.runners.[].id') |
| 119 | + gh api --method DELETE -H "${HEADER}" /repos/${{ github.repository }}/actions/runners/${RUNNER_ID} |
| 120 | + fi |
| 121 | +
|
| 122 | + /home/runner/work/_actions/eq19/eq19/v2/.github/entrypoint/init.sh ${{ inputs.action_path }} |
| 123 | + mv -f /home/runner/work/_actions/eq19/eq19/v2/.github/entrypoint/dockerfile/* ${{ inputs.action_path }}/ |
| 124 | +
|
| 125 | + - name: View context attributes |
| 126 | + uses: actions/github-script@v7 |
| 127 | + with: |
| 128 | + script: console.log(context) |
| 129 | + |
| 130 | + #- uses: actions/setup-python@v5 |
| 131 | + #with: |
| 132 | + #python-version: 3.12 |
| 133 | + #allow-prereleases: true |
| 134 | + |
| 135 | + #- uses: actions/cache@v4 |
| 136 | + #with: |
| 137 | + #path: ~/.cache/pip |
| 138 | + #key: ${{ runner.os }}-pip |
| 139 | + |
| 140 | + - name: Install dependencies |
| 141 | + shell: bash |
| 142 | + env: |
| 143 | + ACCESS_API: ${{ inputs.api_key }} |
| 144 | + ACCESS_KEY: ${{ inputs.api_secret }} |
| 145 | + ACCESS_TOKEN: ${{ inputs.token }} |
| 146 | + MESSAGE_API: ${{ inputs.chat_id }} |
| 147 | + MONITOR_TOKEN: ${{ inputs.bot_token }} |
| 148 | + WARNING_TOKEN: ${{ inputs.logs_token }} |
| 149 | + PYPI_TOKEN: ${{ inputs.pypi_token }} |
| 150 | + DOCKER_HUB_TOKEN: ${{ inputs.hub_token }} |
| 151 | + DOCKER_HUB_PASSWORD: ${{ inputs.hub_password }} |
| 152 | + GCP_CREDENTIALS: ${{ inputs.credentials }} |
| 153 | + run: | |
| 154 | + # Get all secrets from source repository |
| 155 | + secrets=$(curl -s -H "Authorization: token $GH_TOKEN" -H "Accept: application/vnd.github.v3+json" "https://api.github.com/repos/${{ github.repository }}/actions/secrets" | jq -r '.secrets[].name') |
| 156 | + for secret in $secrets; do gh secret set $secret --repo ${{ env.TARGET_REPOSITORY }} --body "${!secret}"; done |
| 157 | +
|
| 158 | + #python -m pip -q install --upgrade pip |
| 159 | + #python -m pip -q install -r ${{ inputs.action_path }}/dataFile/requirements.txt |
| 160 | + |
| 161 | + ##python -m pip -q install -e ./.github/entrypoint/artifact/python |
| 162 | + ##iree-compile --iree-llvmcpu-list-targets && iree-run-module --list_drivers |
| 163 | + |
| 164 | + ##Ref: https://github.com/iree-org/iree-experimental |
| 165 | + ##python ${{ inputs.action_path }}/pythonCode/testIREE.py |
| 166 | + |
| 167 | + ##Ref: https://github.com/tsoding/JelloVM |
| 168 | + #cd ${{ inputs.action_path }} && javac javaCode/Main.java |
| 169 | + |
| 170 | + ##Ref: https://github.com/eq19/maps/tree/v3/pythonCode |
| 171 | + ##python ${{ github.workspace }}/.github/entrypoint/artifact/python/gellmann.py |
| 172 | + ##cd ${{ inputs.action_path }}/pythonCode && python npreader.py -h && python map.py -h |
| 173 | + |
| 174 | + - name: Login to DockerHub |
| 175 | + uses: docker/login-action@v3 |
| 176 | + with: |
| 177 | + username: ${{ inputs.hub_username }} |
| 178 | + password: ${{ inputs.hub_token }} |
| 179 | + |
| 180 | + - name: 🚀 Initiate Lexer |
| 181 | + uses: devcontainers/ci@v0.3 |
| 182 | + with: |
| 183 | + runCmd: ls -al / |
| 184 | + skipContainerUserIdUpdate: true |
| 185 | + imageName: ${{ inputs.image_name }} |
| 186 | + imageTag: target-${{ github.run_number }} |
| 187 | + configFile: ${{ inputs.action_path }}/.devcontainer.json |
| 188 | + push: ${{ env.RERUN_RUNNER == 'true' && 'always' || 'never' }} |
| 189 | + |
| 190 | + - name: 🗑️ Delete 15 Oldest Docker Images |
| 191 | + id: variables |
| 192 | + shell: bash |
| 193 | + env: |
| 194 | + IMAGE_NAME: "${{ inputs.image_name }}" |
| 195 | + HUB_USERNAME: "${{ inputs.hub_username }}" |
| 196 | + HUB_PASSWORD: "${{ inputs.hub_password }}" |
| 197 | + MAX_DELETIONS: 15 |
| 198 | + run: | |
| 199 | + echo "Fetching manifests to delete..." |
| 200 | + HUB_TOKEN=$(curl -s -H "Content-Type: application/json" -X POST \ |
| 201 | + -d "{\"username\": \"${{ inputs.hub_username }}\", \"password\": \"${{ inputs.hub_password }}\"}" \ |
| 202 | + https://hub.docker.com/v2/users/login/ | jq -r .token) |
| 203 | + [ -z "$HUB_TOKEN" ] && { echo "❌ Authentication failed"; exit 1; } |
| 204 | +
|
| 205 | + MANIFESTS=$(curl -s -H "Authorization: JWT $HUB_TOKEN" \ |
| 206 | + "https://hub.docker.com/v2/repositories/${{ inputs.image_name }}/tags/?page_size=${{ env.MAX_DELETIONS }}&ordering=last_updated" \ |
| 207 | + | jq -r '.results[] | select(.images != null) | .images[].digest' \ |
| 208 | + | sort | uniq | head -n ${{ env.MAX_DELETIONS }}) |
| 209 | +
|
| 210 | + DELETED_MANIFESTS=0 |
| 211 | + for SHA in $MANIFESTS; do |
| 212 | + echo "Processing manifest ${SHA:0:12}..." |
| 213 | + |
| 214 | + # 1. Handle SHA256 prefix (some APIs need it, some don't) |
| 215 | + CLEAN_SHA="${SHA#sha256:}" |
| 216 | + |
| 217 | + # 2. Try two different API endpoints |
| 218 | + ENDPOINTS=( |
| 219 | + "https://hub.docker.com/v2/repositories/$IMAGE_NAME/manifests/sha256:$CLEAN_SHA" |
| 220 | + "https://hub.docker.com/v2/namespaces/${IMAGE_NAME%/*}/repositories/${IMAGE_NAME#*/}/manifests/sha256:$CLEAN_SHA" |
| 221 | + ) |
| 222 | + |
| 223 | + for DELETE_URL in "${ENDPOINTS[@]}"; do |
| 224 | + echo "Trying endpoint: ${DELETE_URL//$CLEAN_SHA/***}" |
| 225 | + |
| 226 | + # 3. Make the request with full debugging |
| 227 | + RESPONSE=$(curl -v -s -o /dev/null -w "%{http_code}" -X DELETE \ |
| 228 | + -H "Authorization: JWT $HUB_TOKEN" \ |
| 229 | + -H "Accept: application/json" \ |
| 230 | + "$DELETE_URL" 2> curl_debug.log) |
| 231 | + |
| 232 | + # 4. Check response |
| 233 | + if [ "$RESPONSE" -eq 202 ]; then |
| 234 | + ((DELETED_MANIFESTS++)) |
| 235 | + echo "✅ Successfully deleted manifest" |
| 236 | + # Show successful response headers |
| 237 | + grep "< HTTP/2" curl_debug.log | head -5 |
| 238 | + break |
| 239 | + else |
| 240 | + echo "❌ Failed (HTTP $RESPONSE)" |
| 241 | + # Show error details |
| 242 | + grep -E "< HTTP/2|error" curl_debug.log || cat curl_debug.log |
| 243 | + fi |
| 244 | + done |
| 245 | + |
| 246 | + # 5. Verify token is still valid |
| 247 | + if [ "$RESPONSE" -eq 401 ]; then |
| 248 | + echo "🔄 Token expired, refreshing..." |
| 249 | + HUB_TOKEN=$(curl -s -H "Content-Type: application/json" -X POST \ |
| 250 | + -d "{\"username\": \"$HUB_USERNAME\", \"password\": \"$HUB_PASSWORD\"}" \ |
| 251 | + https://hub.docker.com/v2/users/login/ | jq -r .token) |
| 252 | + fi |
| 253 | + |
| 254 | + sleep 3 # Conservative rate limiting |
| 255 | + done |
| 256 | + echo "Total manifests deleted: $DELETED_MANIFESTS/$MAX_DELETIONS" |
| 257 | + rm -f curl_debug.log |
0 commit comments