diff --git a/.github/actions/push-container/action.yml b/.github/actions/push-container/action.yml
new file mode 100644
index 0000000..e33eb82
--- /dev/null
+++ b/.github/actions/push-container/action.yml
@@ -0,0 +1,33 @@
+name: Push Container
+description: Push a Container
+
+inputs:
+  registry:
+    description: Server address of Docker registry.
+    required: true
+  username:
+    description: Username used to login.
+    required: true
+  password:
+    description: Password or PAT used to login.
+    required: true
+
+  image:
+    description: The name of the image to push.
+    required: true
+  tag:
+    description: The tag of the image to push.
+    required: true
+
+runs:
+  using: "composite"
+  steps:
+    - uses: docker/login-action@v2
+      with:
+        registry: ${{ inputs.registry }}
+        username: ${{ inputs.username }}
+        password: ${{ inputs.password }}
+
+    - shell: bash
+      run: |
+        docker push ${{ inputs.registry }}/${{ inputs.name }}:${{ inputs.tag }}
diff --git a/.github/workflows/llvm-project-epoch-one.yml b/.github/workflows/llvm-project-epoch-one.yml
index 10b0612..95f4d00 100644
--- a/.github/workflows/llvm-project-epoch-one.yml
+++ b/.github/workflows/llvm-project-epoch-one.yml
@@ -27,15 +27,12 @@ jobs:
           platforms: ${{ matrix.platforms }}
           tags: ghcr.io/clangbuiltlinux/llvm-project:stage2-${{ matrix.arch }}
 
-      - name: Login to ghcr.io
+      - name: Push image to ghcr.io
+        uses: ./.github/actions/push-container
         if: ${{ github.repository_owner == 'ClangBuiltLinux' && github.event_name != 'pull_request' && github.ref_name == 'main' }}
-        uses: docker/login-action@v2
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Push image to ghcr.io
-        if: ${{ github.repository_owner == 'ClangBuiltLinux' && github.event_name != 'pull_request' && github.ref_name == 'main' }}
-        run: |
-          docker push ghcr.io/clangbuiltlinux/llvm-project:stage2-${{ matrix.arch }}
+          image: clangbuiltlinux/llvm-project
+          tag: stage2
\ No newline at end of file
diff --git a/.github/workflows/llvm-project-epoch-three.yml b/.github/workflows/llvm-project-epoch-three.yml
index 19516af..92bf62c 100644
--- a/.github/workflows/llvm-project-epoch-three.yml
+++ b/.github/workflows/llvm-project-epoch-three.yml
@@ -28,15 +28,12 @@ jobs:
           platforms: ${{ matrix.platforms }}
           tags: ghcr.io/clangbuiltlinux/llvm-project:stage3-${{ matrix.arch }}
 
-      - name: Login to ghcr.io
+      - name: Push image to ghcr.io
+        uses: ./.github/actions/push-container
         if: ${{ github.repository_owner == 'ClangBuiltLinux' && github.event_name != 'pull_request' && github.ref_name == 'main' }}
-        uses: docker/login-action@v2
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Push image to ghcr.io
-        if: ${{ github.repository_owner == 'ClangBuiltLinux' && github.event_name != 'pull_request' && github.ref_name == 'main' }}
-        run: |
-          docker push ghcr.io/clangbuiltlinux/llvm-project:stage3-${{ matrix.arch }}
+          image: clangbuiltlinux/llvm-project
+          tag: stage3
\ No newline at end of file
diff --git a/.github/workflows/llvm-project-epoch-two.yml b/.github/workflows/llvm-project-epoch-two.yml
index b8009c9..cb3186d 100644
--- a/.github/workflows/llvm-project-epoch-two.yml
+++ b/.github/workflows/llvm-project-epoch-two.yml
@@ -28,15 +28,12 @@ jobs:
           platforms: ${{ matrix.platforms }}
           tags: ghcr.io/clangbuiltlinux/llvm-project:stage2-${{ matrix.arch }}
 
-      - name: Login to ghcr.io
+      - name: Push image to ghcr.io
+        uses: ./.github/actions/push-container
         if: ${{ github.repository_owner == 'ClangBuiltLinux' && github.event_name != 'pull_request' && github.ref_name == 'main' }}
-        uses: docker/login-action@v2
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Push image to ghcr.io
-        if: ${{ github.repository_owner == 'ClangBuiltLinux' && github.event_name != 'pull_request' && github.ref_name == 'main' }}
-        run: |
-          docker push ghcr.io/clangbuiltlinux/llvm-project:stage2-${{ matrix.arch }}
+          image: clangbuiltlinux/llvm-project
+          tag: stage2
\ No newline at end of file