Repository: conan-io/conan

Issue:
[feature] upload the binary package just created with `create`/`export-pkg`
### What is your suggestion?

In CI, it's very common to build (create) a binary package, and then upload it to the remote.

Recently, i've tried to get the exact pattern to match the binary package that just created by `conan create` or `conan export-pkg`, but failed to find an easy way.

Let me show some example.

Example 1, `conan create` a binary package, upload the package and all its dependencies just built.

```
conan create . -b=missing -f=json > graph.json
conan list -g graph.json -gb build -f json > pkglist.json
conan upload --list=pkglist.json -r=remote -c
```

Example 2, `conan create` a binary package, upload **only** the package created, not any of its dependencies. This is not that intuitive as Example 1, and wasteing time and space (caculate the graph twice, and generates things twice). We need `install` first to build all dependencies, then `create` to build the package we want. 

```
conan install . -b=missing
conan create . -f=json > graph.json
conan list -g graph.json -gb build -f json > pkglist.json
conan upload --list=pkglist.json -r=remote -c
```

Example 3, `conan export-pkg` a package and upload it. `conan list  -gb build` can't help anymore, it seems to ignore the root node, which is the package we want, and even it has `"binary": "Build"`. I need to specify both the name and the version. 

The hardest part is acquiring the version. The files they live are varies (conanfile.py, or any other). The way to acquire its value to the CI shell are also varies (powershell in Windows and bash in Linux) ....

```
# firstly, we need to get the version
version=`head -n 1 version.txt | tr -d '\n'`
# conan install 
conan install conanfile.py -pr:a $profile --build=missing -f=json > graph.$profile.json
conan list --graph=graph.$profile.json --graph-binaries=build -f=json > deps_to_upload.$profile.json
# upload the dependencies just build
conan upload -r remote -l deps_to_upload.$profile.json -c
# build the library
conan build conanfile.py -pr:a $profile
# create conan package
conan export-pkg conanfile_package.py -pr:a $profile
# upload the package
conan upload -r remote "name/$version@user#latest:*#latest" -c
```

Things could be easier if

+ `conan create` / `conan export-pkg` can optionally output the accurate pattern (`name/version@user/channel:rrev#package_id:prev`) of package just created, which can be used by `conan upload` later.



### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide


Discussion:
Hi @X1aomu 

Thanks for your suggestions.

I'd like to clarify some issues first:

> Example 2, conan create a binary package, upload only the package created, not any of its dependencies. 

This is a broken approach. You shouldn't do ``conan install --build=missing`` + ``conan create`` + ``conan upload only the created one``. This means that you are uploading a binary that was built against non-existing binaries in the dependencies. This binary will not be reproducible, and it can fail in different scenarios. It is only recommended to upload packages that already have their dependencies binaries in the server or uploading the dependencies too. This is why ``Example1`` is the recommended approach, everything that was built locally should be uploaded, or it shouldn't have been built locally in the first place.


> Example 3, conan export-pkg

This might be a different issue, I'll have a look at this
I see that the "exported" binary package has ``"recipe": "Consumer"`` which seems the main issue. I am contributing a fix in https://github.com/conan-io/conan/pull/15504



Patch:
diff --git a/conan/api/subapi/export.py b/conan/api/subapi/export.py
index 9c3a59c9525..ab8d410cdd2 100644
--- a/conan/api/subapi/export.py
+++ b/conan/api/subapi/export.py
@@ -2,7 +2,7 @@
 from conan.internal.conan_app import ConanApp
 from conans.client.cmd.export import cmd_export
 from conans.client.conanfile.package import run_package_method
-from conans.client.graph.graph import BINARY_BUILD
+from conans.client.graph.graph import BINARY_BUILD, RECIPE_INCACHE
 from conans.model.package_ref import PkgReference
 from conans.util.files import mkdir
 
@@ -52,6 +52,7 @@ def export_pkg(self, deps_graph, source_folder, output_folder):
         cache.assign_prev(pkg_layout)
         pkg_node.prev = prev
         pkg_node.pref_timestamp = pref.timestamp  # assigned by assign_prev
+        pkg_node.recipe = RECIPE_INCACHE
         pkg_node.binary = BINARY_BUILD
         # Make sure folder is updated
         final_folder = pkg_layout.package()
diff --git a/conan/cli/commands/export_pkg.py b/conan/cli/commands/export_pkg.py
index 3007d73af80..ebc9e94603e 100644
--- a/conan/cli/commands/export_pkg.py
+++ b/conan/cli/commands/export_pkg.py
@@ -93,9 +93,10 @@ def export_pkg(conan_api, parser, *args):
 
     if test_conanfile_path:
         from conan.cli.commands.test import run_test
-        deps_graph = run_test(conan_api, test_conanfile_path, ref, profile_host, profile_build,
-                              remotes=remotes, lockfile=lockfile, update=False, build_modes=None)
-        # TODO: Do something with lockfile, same as create()
+        # same as ``conan create`` the lockfile, and deps graph is the one of the exported-pkg
+        # not the one from test_package
+        run_test(conan_api, test_conanfile_path, ref, profile_host, profile_build,
+                 remotes=remotes, lockfile=lockfile, update=False, build_modes=None)
 
     conan_api.lockfile.save_lockfile(lockfile, args.lockfile_out, cwd)
     return {"graph": deps_graph,


Test patch:
diff --git a/conans/test/integration/command/export_pkg_test.py b/conans/test/integration/command/export_pkg_test.py
index 37642e19423..4e4967e9ccd 100644
--- a/conans/test/integration/command/export_pkg_test.py
+++ b/conans/test/integration/command/export_pkg_test.py
@@ -283,8 +283,8 @@ def test_export_pkg_json(self):
         client.save({"conanfile.py": GenConanfile("pkg", "0.1")})
 
         # Wrong folders
-        client.run("export-pkg . --format=json")
-        graph = json.loads(client.stdout)
+        client.run("export-pkg . --format=json", redirect_stdout="exported.json")
+        graph = json.loads(client.load("exported.json"))
         node = graph["graph"]["nodes"]["0"]
         assert "pkg/0.1" in node["ref"]
         # https://github.com/conan-io/conan/issues/15041
@@ -295,6 +295,12 @@ def test_export_pkg_json(self):
         assert node["rrev_timestamp"] is not None
         assert node["prev_timestamp"] is not None
 
+        # Make sure the exported json file can be used for ``conan lsit --graph`` input to upload
+        client.run("list --graph=exported.json -gb=build --format=json")
+        pkglist = json.loads(client.stdout)
+        revs = pkglist["Local Cache"]["pkg/0.1"]["revisions"]["485dad6cb11e2fa99d9afbe44a57a164"]
+        assert "da39a3ee5e6b4b0d3255bfef95601890afd80709" in revs["packages"]
+
     def test_export_pkg_no_ref(self):
         client = TestClient()
         conanfile = """import os